我很好奇为什么这个命令:
for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;
输出 /mydir 目录中最后的十个文件,但是
/bin/bash -c "for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;"
输出 "syntax error near unexpected token '[file in /mydir]'"
我很好奇为什么这个命令:
for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;
输出 /mydir 目录中最后的十个文件,但是
/bin/bash -c "for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;"
输出 "syntax error near unexpected token '[file in /mydir]'"
你正在使用双引号,因此父shell会在将参数传递给/bin/bash
之前插入反引号和变量。
因此,你的/bin/bash
将接收以下参数:
-c "for f in x
y
z
...
; do echo ; done;"
这是一种语法错误。
为了避免这种情况,使用单引号来传递参数:
/bin/bash -c 'for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;'
/bin
,您的第一个示例输出如下:rmdir
sh
sleep
stty
sync
tcsh
test
unlink
wait4path
zsh
/bin/bash: -c: line 1: syntax error near unexpected token `sh'
/bin/bash: -c: line 1: `sh'
因为命令替换在两种情况下都发生在你的第一个 shell 中,所以你的第一个例子起作用了(当创建命令行时,换行符被删除了),但是在第二个例子中却不起作用—— 它们保留在字符串中,这要归功于你的""
。使用 echo
而不是 bash -c
可以展示这一点:
$ 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
从中可以看出你的 bash -c
会看到什么,以及为什么它不起作用——sh
在 do
之前!
你可以使用单引号代替,但这将导致子命令在新的子 shell 中运行:
$ /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
如果这不行的话,你需要消除这些换行符:
$ /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