变量中的Execute命令不执行管道的后半部分 [英] Execute command in a variable don't execute the latter part of a pipe

查看:70
本文介绍了变量中的Execute命令不执行管道的后半部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现从变量扩展的命令不会在管道中运行后面的部分.例如,如下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:helloman.另一方面,使用单个参数(由于使用了引号)运行命令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,然后对其进行单词拆分.它被扩展为相同的外观字符串,但是现在为重定向已为时已晚.因此它被拆分为单词echohelloman|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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆