我很好奇,为什么条命令:/bin/bash -c与直接执行命令有什么不同?
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;"
输出 “语法错误附近意外的标记 '[中/ MYDIR文件]'”
我很好奇,为什么条命令:/bin/bash -c与直接执行命令有什么不同?
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;"
输出 “语法错误附近意外的标记 '[中/ MYDIR文件]'”
您正在使用双引号,所以在将参数传递给/bin/bash
之前,父shell会插入反引号和变量。
因此,你的/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'
因为命令替换发生在你的第一壳在这两个例如,你的第一个作品(在制作命令行时删除了换行符),但在第二种情况下它不会 - 由于你的""
,它们仍保留在字符串中。使用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
一次偶然的机会,这样的回答帮我解决一个奇怪的错误(部署/ Capistrano的/作曲/等),根本原因:双引号VS 。在一个命令中的单引号自动拼接在一起。谢谢。 – Wolfram 2015-01-26 11:24:09