/bin/bash -c 与直接执行命令有何不同?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26167803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does /bin/bash -c differ from executing a command directly?
提问by JivanAmara
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
输出 /mydir 中的最后十个文件,但
/bin/bash -c "for f in `/bin/ls /mydir | sort | tail -n 10`; do echo $f; done;"
Outputs "syntax error near unexpected token '[file in /mydir]'"
输出“意外标记附近的语法错误'[/mydir 中的文件]'”
回答by nneonneo
You are using double-quotes, so the parent shell is interpolating backticks and variables before passing the argument to /bin/bash
.
您正在使用双引号,因此父 shell 在将参数传递给/bin/bash
.
Thus, your /bin/bash
is receiving the following arguments:
因此,您/bin/bash
将收到以下参数:
-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;'
回答by Carl Norum
Different newline handling in your subcommand output. For example on my machine, using /bin
I get this output for your first example:
子命令输出中的不同换行处理。例如,在我的机器上,使用/bin
我为您的第一个示例获取此输出:
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 firstshell 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:
因为在这两种情况下命令替换都发生在你的第一个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
You can see from that what your bash -c
is seeing and why it doesn't work - the sh
comes before the do
!
您可以从中看到您bash -c
所看到的内容以及为什么它不起作用 -sh
出现在do
!
You can use single quotes instead, but that will cause the subcommand to run in your new subshell:
您可以改用单引号,但这会导致子命令在您的新子 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
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