mpenkov
mpenkov

Reputation: 21906

Using bash -c with loops and standard output redirection

Why does the standard output from the following commands differ?

command1:

for ((i=0; i<10; i=i+1)); do echo $i; done

command2:

bash -c "for ((i=0; i<10; i=i+1)); do echo $i; done"

command1 prints the integers 1 to 10 on a separate line, as expected. command2 prints 10 on each line.

What do I need to do to get command2 to print the same thing as command1?

The long story:

I often need to run an executable on a large number of files and capture the output of the entire process. I use a for loop similar to command1 in a separate file called my_script.sh.

I can then get the output using:

bash my_script.sh > results.txt

Since it's a bit of a pain to create a separate my_script.sh file for trivial for loops, I was hoping to achieve the same thing by using "bash -c", but ran into this problem.

Thanks for any suggestions. Looking forward to replies.
Misha

Upvotes: 4

Views: 3455

Answers (1)

cdhowie
cdhowie

Reputation: 168988

What do I need to do to get command2 to print the same thing as command1?

You need to fix this line:

bash -c "for ((i=0; i<10; i=i+1)); do echo $i; done"

To say this instead:

bash -c "for ((i=0; i<10; i=i+1)); do echo \$i; done"

What's happening is that the $i sequence is being interpreted by the shell you are running bash from, and it is substituting its own i variable into the string before passing it off to the new bash instance to be executed. So by the time the new bash sees the string, it is:

for ((i=0; i<10; i=i+1)); do echo 10; done

Assuming that i contained the value "10".

(When I first ran the second script, which I did before running the first, it wrote out 10 blank lines, because I had no i variable defined, and so it was substituting in the empty string.)

Upvotes: 14

Related Questions