For loop after upgrading

Hello everybody,

I upgraded from Ubuntu 12.04 to 14.04, so some of my scripts in bash does NOT work, for example:

#!/bin/bash

# Some codes goes here


        for ((offset=$thumbStart; offset<=$thumbEnd; offset+=10)) # LINE 459
        do
        printf -v outfile "$filePNG"_"%03d.png" "$((++n))"

        ffmpeg -itsoffset -$offset -i $fileFinal -vcodec mjpeg -vframes 1 -an -f rawvideo -s 640x480 "$outfile"

        done

        mv *.png $path2thumb

         fi # End if [ $thumb -eq 0 ]

        multipleThumbs=$?

        } # end multipleThumbs


output is:

# sh runScript.sh 
smartCode.sh: 459: functions.sh: Syntax error: Bad for loop variable

Thanks in advance

It would appear that the new version of bash that you are now running has an additional keyword that you can no longer use as a variable name in your scripts. Try changing:

        for ((offset=$thumbStart; offset<=$thumbEnd; offset+=10)) # LINE 459
        do
        printf -v outfile "$filePNG"_"%03d.png" "$((++n))"

        ffmpeg -itsoffset -$offset -i $fileFinal -vcodec mjpeg -vframes 1 -an -f rawvideo -s 640x480 "$outfile"

to:

        for ((Offset=$thumbStart; Offset<=$thumbEnd; Offset+=10)) # LINE 459
        do
        printf -v outfile "$filePNG"_"%03d.png" "$((++n))"

        ffmpeg -itsoffset -$Offset -i $fileFinal -vcodec jpeg -vframes 1 -an -f rawvideo -s 640x480 "$outfile"

and see if that works.

I tried your example, I've got the same error, so I made another example:

#!/bin/bash

for (( i=0; i<=10; i+=2 ))
do
 echo "Welcome $i times" 
done

then

sh.sh: 3: sh.sh: Syntax error: Bad for loop variable

It would be interesting to know what version of bash you are actually using as I can only create that error in " dash ".
bash -version

Last login: Sat Aug 13 12:31:55 on ttys000
AMIGA:barrywalker~> dash
AMIGA:\u\w> #!/bin/bash

for (( i=0; i<=10; i+=2 ))
do
 echo "Welcome $i times" 
doneAMIGA:\u\w> AMIGA:\u\w> dash: 3: Syntax error: Bad for loop variable
AMIGA:\u\w> dash: 3: Syntax error: "do" unexpected
AMIGA:\u\w> AMIGA:\u\w> Welcome  times
AMIGA:\u\w> exit
dash: 5: doneexit: not found
AMIGA:\u\w> exit
AMIGA:barrywalker~> 
AMIGA:barrywalker~> #!/bin/bash
AMIGA:barrywalker~> 
AMIGA:barrywalker~> for (( i=0; i<=10; i+=2 ))
> do
>  echo "Welcome $i times" 
> done
Welcome 0 times
Welcome 2 times
Welcome 4 times
Welcome 6 times
Welcome 8 times
Welcome 10 times
AMIGA:barrywalker~> _

Here you go

# bash -version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Hi.

Because of the sh.sh , it looks to me like there is an alias for bash , or sh.sh is named bash in /bin

Thsi code worked for me in:

OS, ker|rel, machine: Linux, 3.16.0-73-generic, x86_64
Distribution        : Ubuntu 14.04.2 (KDE, Trusty Tahr) 
bash GNU bash 4.3.11

as well as in:

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.4 (jessie) 
bash GNU bash 4.3.30

Best wishes ... cheers, drl

It seems something strange with it:

# mv sh.sh test.sh
# sh test.sh 
test.sh: 3: test.sh: Syntax error: Bad for loop variable

Hi.

It needs bash , so try:

bash sh.sh

I did get it to fail with:

sh sh.sh

The command sh is not the same as bash ... cheers, drl

Please show us the output from the command:

type bash

and the output from the command:

head sh.sh | od -bc

or, if you have since renamed sh.sh to test.sh , the output from the command:

head test.sh | od -bc

Like drl said, either call you script like this:

# bash runScript.sh

or ensure it is executable and use:

./runScript.sh

which uses the shebang on the first line of your script:

#!/bin/bash

If you call it like you did in post #1:

sh runScript.sh

on a typical Ubuntu installation, then dash gets called instead of bash .
dash does not know that kind of for loop.

# type bash
bash is /bin/bash
head test.sh | od -bc
0000000 043 041 057 142 151 156 057 142 141 163 150 012 012 146 157 162
          #   !   /   b   i   n   /   b   a   s   h  \n  \n   f   o   r
0000020 040 050 050 040 151 075 060 073 040 151 074 075 061 060 073 040
              (   (       i   =   0   ;       i   <   =   1   0   ;    
0000040 151 053 075 062 040 051 051 012 144 157 012 040 145 143 150 157
          i   +   =   2       )   )  \n   d   o  \n       e   c   h   o
0000060 040 042 127 145 154 143 157 155 145 040 044 151 040 164 151 155
              "   W   e   l   c   o   m   e       $   i       t   i   m
0000100 145 163 042 040 012 144 157 156 145 012 012 074 074 103 117 115
          e   s   "      \n   d   o   n   e  \n  \n   <   <   C   O   M
0000120 115 012 164 150 165 155 142 123 164 141 162 164 075 060 012 164
          M  \n   t   h   u   m   b   S   t   a   r   t   =   0  \n   t
0000140 150 165 155 142 105 156 144 075 061 060 060 012
          h   u   m   b   E   n   d   =   1   0   0  \n
0000154

This works fine

How can I change from dash to bash, I use to run my scripts using sh file.sh

Using the command sh scriptname runs your script with sh ; not with bash . Run your bash script with bash :

bash sh.sh

or make you script executable:

chmod +x sh.sh

and run your script by its name in the directory where it resides:

./sh.sh

or, after making your script executable, move your script into a directory in the list of directories contained in the expansion of $PATH and just execute it by its name:

sh.sh

I don't face these kind of problems in another server, I can run my scripts anywhere using sh file.sh, what can I change to do the same thing?

Well this is a test script from another server:

# sh date.sh 
08-14-16
05:11:55
14-08-2016 05:11:55
1471140715
Sun Aug 14 05:11:55 AST 2016
1471133515
7200
Sun Aug 14 03:11:55 AST 2016

#ls -l date.sh
-rw-r--r-- 1 root          root           352 Aug 17  2015 date.sh

# type bash
bash is /bin/bash

# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
# bash -version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Try a little lateral thinking:-

bash sh.sh

If your code works then what I and Scrutinizer suggested about " dash " is being used as the pure shell and NOT a " bashism " version of it...

Explicitly using sh to run file.sh will exclude bash / ksh in the first place UNLESS sh is an alias or a link to one of those advanced shells. On your other server, check if sh is one of those.

Does date.sh contain the same type of for loop?

I gave you three suggestions in post #12 in this thread that will probably work on most, if not all, of your systems. If you choose to ignore that advice, and insist on executing you bash scripts with the command:

sh bash_script

you have one choice: Remove all code from all of the scripts that you want to invoke with sh that was not present in a 1970's Bourne shell. The commands sh and bash are not the same. If you are unwilling to use bash to execute your bash scripts, you have to change your scripts to be Bourne shell scripts that you can execute with sh , or limit yourself to never use any server that does not have sh as a link to a shell that supports the bash extensions to the Bourne shell that your scripts use.

Of course, you could replace /bin/sh with a bash shell, but if you do that you may end up with a system that will no longer boot.

But, it would be MUCH better if you would forget the ridiculous assumption that you can execute an awk with the sed command, compile a C program conforming the the 2011 C standard with a 1970's C compiler, or run a bash script using a shell named sh .

Well, I did some more stuffs, I reinstalled the server, the bash version now is: "GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu)", I can use both of "bash" and "sh", thank you for your suport