Shell 使用命令编写变量作用域脚本

Shell Script Variable Scope with commnd

我在 Shell 脚本编写中遇到了一件有趣的事情,但不是 100% 确定为什么会这样

我尝试了以下脚本:

#!/bin/sh
CMD="curl -XGET http://../endpoint";
var1=eval $CMD | sed -e 's/find/replace/g';
echo $var1;  # Output: printed the value on this line
echo $var1;  # Output: blank/no data printed (Why it is blank?)

我不得不更改用反引号括起来的变量中的命令,以便根据需要多次打印变量。

CMD="curl -XGET http://../endpoint";
var1=`eval $CMD | sed -e 's/find/replace/g'`;
echo $var1;  # Output: printed the value on this line 
echo $var1;  # Output: printed the value on this line 

感觉跟变量命令作用域有关

如能阐明我的理解,将不胜感激!

更新: 我尝试了以下命令,它在我的环境中工作。

#!/bin/sh
CMD="curl -XGET http://www.google.com/";
var1=eval $CMD | sed -e 's/find/replace/g';
echo $var1;  # Output: printed the value on this line
echo "######";
echo $var1;  # Output: blank/no data printed (Why it is blank?)

第一个例子与您想象的不一样。

echo 均未打印任何内容。让他们 echo "[$var1]" 看到。

您需要 运行 命令的反引号并捕获其输出。

您的第一次尝试是 运行将 $CMD | sed -e 's/find/replace/g'; 管道与包含 var1$CMD 环境设置为值 eval

您也不应该将命令放在字符串中(或者通常使用 eval)。有关原因的更多信息,请参阅 http://mywiki.wooledge.org/BashFAQ/001

sh/bash 允许您 运行 在其环境中使用变量的命令,而无需永久修改 shell 中的变量。这很棒,因为你可以,例如运行 一次使用某种语言的命令,而无需更改整个用户或系统的语言:

$ LC_ALL=en_US.utf8 ls foo
ls: cannot access foo: No such file or directory
$ LC_ALL=nb_NO.utf8 ls foo
ls: cannot access foo: Ingen slik fil eller filkatalog

然而,这意味着当你尝试做

var=this is some command

你触发了这个语法。

表示"run the command is a command and tell it that the variable var is set to this"

它不会把"this is my string"赋值给变量,也绝对不会把"this is a string"当作一个命令求值,然后把它的输出赋值给var

鉴于此,我们可以看看实际发生了什么:

CMD="curl -XGET http://../endpoint";
var1=eval $CMD | sed -e 's/find/replace/g';  # No assignment, output to screen
echo $var1;  # Output: blank/no data printed
echo $var1;  # Output: blank/no data printed

没有范围问题,也没有不一致:变量从未被赋值,也从未被 echo 语句写入。

var=`some command`(或者最好是 var=$(some command))有效,因为这是将程序输出分配给变量的有效语法。