I\'m curious why the commmand:
for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;
Outputs the last ten files in /mydir, but
You are using double-quotes, so the parent shell is interpolating backticks and variables before passing the argument to /bin/bash
.
Thus, your /bin/bash
is receiving the following arguments:
-c "for f in x
y
z
...
; do echo ; done;"
which is a syntax error.
To avoid this, use single quotes to pass your argument:
/bin/bash -c 'for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;'
Different newline handling in your subcommand output. For example on my machine, using /bin
I get this output for your first example:
rmdir
sh
sleep
stty
sync
tcsh
test
unlink
wait4path
zsh
But with the latter:
/bin/bash: -c: line 1: syntax error near unexpected token `sh'
/bin/bash: -c: line 1: `sh'
Because the command substitution takes place in your first shell in both cases, your first one works (the newlines are stripped out when making the command line), but in the second case it doesn't - they remain in the string thanks to your ""
. Using echo
rather than bash -c
can showcase this:
$ echo "for f in `/bin/ls /bin | sort | tail -n 10`; do echo \$f; done"
for f in rmdir
sh
sleep
stty
sync
tcsh
test
unlink
wait4path
zsh; do echo $f; done
You can see from that what your bash -c
is seeing and why it doesn't work - the sh
comes before the do
!
You can use single quotes instead, but that will cause the subcommand to run in your new subshell:
$ /bin/bash -c 'for f in `/bin/ls /bin | sort | tail -n 10`; do echo $f; done'
rmdir
sh
sleep
stty
sync
tcsh
test
unlink
wait4path
zsh
If that's not ok, you need to get rid of those newlines:
$ /bin/bash -c "for f in `/bin/ls /bin | sort | tail -n 10 | tr '\n' ' '`; do echo \$f; done"
rmdir
sh
sleep
stty
sync
tcsh
test
unlink
wait4path
zsh