如果我运行此程序,它将起作用。
dig +short myip.opendns.com @resolver1.opendns.com
如果我这样做了,那就行不通了
ip=$(dig +short myip.opendns.com @resolver1.opendns.com) | echo "$ip"
如何通过管道命令传递变量?
答案 0 :(得分:6)
你没有。
使用
ip=$(dig +short myip.opendns.com @resolver1.opendns.com) && echo "$ip"
(如果第一个命令失败,则不会回显)
或
ip=$(dig +short myip.opendns.com @resolver1.opendns.com); echo "$ip"
(仍然回显$ ip)
答案 1 :(得分:1)
非常简短的版本是管道将一个(一组)命令的标准输出连接到另一个(标准)输入。但是,要了解实际管道的细微差别可能会很棘手。在您的示例中,由于当前外壳程序中不存在该变量(或者回显将能够使用它),因此我尚不清楚变量分配在何处发生。
无论如何,您的构造都会将变量赋值的标准输出传递给echo输入。我认为变量分配的标准输出为空(如果分配变量,则在命令行上不会输出)。
我在这里找到了bash(Unix)中管道的非常详细的解释:
What is a simple explanation for how pipes work in Bash?
尤其要看rkachach提供的答案。
此外,您创建的管道(Corentin Limier在其出色的答复中对其进行了改进)作为测试也不是很可靠。以这种情况下的命令加载ip错误为例:
$ ip=$(dig +short myip.opendns.co @resolver1.opendns.co) && echo "$ip"
dig: couldn't get address for 'resolver1.opendns.co': not found
如您所见,错误(来自dig命令的标准错误)已加载到ip中,此测试无法对其进行管理。
答案 2 :(得分:1)
我相信您在这里混淆了两件事:管道的使用和变量的使用。
让我给您一个简单的管道示例:
grep "Something" filename.txt | sort
如您所见,管道的意思是“获取一个命令的输出并将其用作下一个命令的输入”,在这种情况下:将文件过滤在一个特定的单词上,并按字母顺序进行排序。
让我给您一个简单的变量示例:
ip=$(dig +short myip.opendns.com @resolver1.opendns.com)
do_something_else
echo $ip
如您所见,这看起来更像是脚本的一部分,您需要在其中存储一些您不会立即使用的信息。
因此,简而言之:如果您想立即将命令的输出用作下一个命令的输入(它也可能立即用于下一个下一个命令,...),那么管道很有用。 br /> 但是,如果您想做更复杂的事情(例如不立即使用而保留结果),则可以使用变量。
答案 3 :(得分:1)
为了完整起见,实际上使用您使用的语法完全丢失了分配。
通常,如果您要这样做
i=$(echo 20)
然后启动一个fork来运行echo 20
,主代码使用该fork的输出来分配局部变量i。像往常一样,叉子中的其他所有东西都被遗忘了。
完成时
echo 10 | echo $i
发生的情况是启动了2个fork,每个echo
命令一个,而1的输出连接到另一个的输入。该操作没有任何保留。还要注意,$ i的值是在两个分支中的任何一个实际启动之前解析的。
这样做的时候
i = $(echo 20) | echo $i
启动一个fork来执行i = $(echo 20)
。反过来,这会启动一个分叉来执行echo 20
。
启动另一个fork来执行echo $i
,并且$ i的值在开始执行之前完全解析。
第一个fork存储一个本地值i
,但是当该fork退出时会忘记它!