How to run a script with a for loop by sudo command

1.9k Views Asked by At

I was making a script, when I found a problem with sudo command and for loop.

I have this test script

for i in {0..10..2}
do
    echo "Welcome $i times"
done

Normal output should be this:

Welcome 0 times
Welcome 2 times
Welcome 4 times
Welcome 6 times
Welcome 8 times
Welcome 10 times

But it shows this:Welcome {0..10..2} times any ideas ?

bash version:4.3.11(1)-release

4

There are 4 best solutions below

1
On BEST ANSWER

The shell in sudo does not do brace expansion.

$ cat s.sh 
echo $SHELL
echo $SHELLOPTS
for i in {0..10..2}
      do
        echo "Welcome $i times"
      done

$ ./s.sh
/bin/bash
braceexpand:hashall:interactive-comments
Welcome 0 times
Welcome 2 times
Welcome 4 times
Welcome 6 times
Welcome 8 times
Welcome 10 times

$ sudo ./s.sh
/bin/bash

Welcome {0..10..2} times

Use seq() as others have suggested.

2
On

I'm not sure if I have understood you correctly, but you can use below code to generate the same output. Here's my test script

for i in $(seq 0 5)
  do
     echo "Welcome $(( $i * 2)) times"
 done

Output

Welcome 0 times
Welcome 2 times
Welcome 4 times
Welcome 6 times
Welcome 8 times
Welcome 10 times

More detail on seq command can be found here

2
On

Ok, the script should be this:

for i in $(seq 0 5) do echo "Welcome $(( $i * 2)) times" done thank you my-thoughts.

2
On

The {0..10..2} syntax is only supported in Bash 4.

For Bash 3, use this syntax instead:

$ 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

You can see what is happening in Bash 3.2 if you remove the step part of the brace expansion:

bash-3.2$ for i in {0..10..2}; do echo "i=>$i"; done
i=>{0..10..2}
bash-3.2$ for i in {0..10}; do echo "i=>$i"; done
i=>0
i=>1
i=>2
i=>3
i=>4
i=>5
i=>6
i=>7
i=>8
i=>9
i=>10

BUT on Bash 4, it works as you desired it to:

bash-4.3$ for i in {0..10..2}; do echo "i=>$i"; done
i=>0
i=>2
i=>4
i=>6
i=>8
i=>10

Edit

As Nathan Wilson correctly points out, this is probably the result of the Bash option braceexpand being negative.

You can set this value with set:

$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:posix
$ for i in {0..5}; do echo "i=>$i"; done
i=>0
i=>1
i=>2
i=>3
i=>4
i=>5
$ set +B
$ echo $SHELLOPTS
emacs:hashall:histexpand:history:interactive-comments:monitor:posix
$ for i in {0..5}; do echo "i=>$i"; done
i=>{0..5}