变量中的Execute命令不执行管道的后半部分 [英] Execute command in a variable don't execute the latter part of a pipe
问题描述
我发现从变量扩展的命令不会在管道中运行后面的部分.例如,如下test.sh
:
I have found that the command expanded from variable won't run the latter parts in a pipe. For example, as following test.sh
:
#!/bin/bash
y='echo hello man | awk "{print \$1}"'
$y
eval $y
y='echo hello'
$y
脚本的输出为:
hello man | awk "{print \$1}"
hello
hello
第一个$y
仅执行echo hello man
,但不执行管道的awk "{print $1}"
.那是为什么?
我的bash版本是4.3.48
.
The first $y
only execute echo hello man
but not execute awk "{print $1}"
of the pipe. That's why?
My bash version is 4.3.48
.
推荐答案
这是因为变量在管道和重定向完成后会扩展.因此,在这种情况下,|
只是echo
的另一个参数,而不是由外壳程序解释的管道.
That's because the variable is expanded after the pipes and redirection is already done. So in that case |
is just another argument to echo
, not a pipe that's interpreted by the shell.
推荐阅读: http://mywiki.wooledge.org/BashFAQ/050
执行命令时
echo hello man | awk '{print $1}'
shell将看到|
并设置管道,它的一侧将运行命令echo hello man
,而另一侧将运行awk '{print $1}'
.然后,这些命令会进行单词拆分,因此您可以使用以下两个参数运行命令echo
:hello
和man
.另一方面,使用单个参数(由于使用了引号)运行命令awk
the shell will see the |
and setup a pipeline, on one side it will run the command echo hello man
and on the other awk '{print $1}'
. The commands then get subjected to word splitting so you run the command echo
with 2 arguments: hello
and man
. On the other side you run the command awk
with a single argument (because of the quoting) "{print \$1}"
尽管该命令以字符串形式存储,但是外壳程序首先查看命令$y
,却看不到重定向.然后,它展开$y
,然后对其进行单词拆分.它被扩展为相同的外观字符串,但是现在为重定向已为时已晚.因此它被拆分为单词echo
,hello
,man
,|
,awk
,"{print
,\$1}"
(请注意,awk
的参数现在已被拆分,因为其中的引号字符串是字符串的一部分,而不是语法)
When that command is stored as a string though the shell first looks at the command $y
and sees no redirection to do. It then expands $y
and then does word splitting on it. It gets expanded to the same looking string, but now it's too late for redirection. So it gets split into the words echo
, hello
, man
, |
, awk
, "{print
, \$1}"
(note that the argument to awk
now gets split because the quotes inside the string are part of the string, not syntactical)
该列表中的第一个单词是echo
,这就是命令,所有其余单词都作为参数传递给它,这就是为什么看到输出的原因
The first word in that list is echo
so that's the command, and all the rest of the words are passed as arguments to it, which is why you see the output
hello man | awk "{print \$1}"
当您执行eval
行时,它会使用相同的字符串,并告诉bash
对其进行解析,就好像它已经被键入一样,因此管道再次变得语法化并导致管道.
When you do the eval
line, it takes that same string and tells bash
to parse it as though it had been typed so the pipe once again becomes syntatical and causes the pipeline.
因为echo
将其参数放在同一行上,所以有时很难看清所发生的情况,如果我们将其替换为printf '%s\n'
,则每个参数都将成为其自己的行:
Because echo
puts its arguments on the same line it's a little tougher sometimes to see what's happening, if we replace it with printf '%s\n'
each argument will become its own line though:
$ y='printf %s\n hello man | awk "{print \$1}"'
$ $y
hello
man
|
awk
"{print
\$1}"
这篇关于变量中的Execute命令不执行管道的后半部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!