根据变量所处的上下文,变量扩展的工作方式是否有所不同?

根据变量所处的上下文,变量扩展的工作方式是否有所不同?

假设我做了以下事情:

IFS=,
x="hello,hi,world"
y=$x

y将有 string hello hi world,所以它就像y=$x被替换为:

y="hello hi world"

现在假设我有以下脚本:

IFS=,
x="hello,hi,world"
if [ $x = "hello hi world" ]
then
    echo "equal"
fi

运行上述脚本时,出现以下错误:

test.sh: line 3: [: too many arguments

我假设我收到此错误是因为该语句在执行时if [ $x = "hello hi world" ]被替换为if [ hello hi world = "hello hi world" ]而不是被替换。if [ "hello hi world" = "hello hi world" ]

因此,这意味着该变量$x根据其所处的上下文以两种不同的方式扩展(一次用双引号扩展,另一次不带双引号扩展)。

我对么?

答案1

y将有字符串hello hi world

不,不会的。变量赋值中的扩展不受分词或文件名通配的影响。 (从某种意义上说,它们总是表现得像被双引号括起来一样。)参见:什么时候需要双引号?

$ IFS=,
$ x="hello,hi,world"; y=$x
$ echo "$y"
hello,hi,world

我假设我收到此错误是因为该语句if [ $x = "hello hi world" ]被替换为if [ hello hi world = "hello hi world" ]

是的,有点像。它不是基于文本的替换,但由于$x此处未引用,因此它确实经历了分词,并且该[命令看到六个不同的参数(hellohiworld=hello hi world]),而不是它期望的四个。

答案2

如果在赋值中使用变量,则它们在引用方面的行为确实有所不同。在

y=$x

不执行分词,即它相当于

y="$x"

但在正常的参数扩展中,例如

if [ $x =

是否有引号确实有影响。顺便说一句:使用引号$x不会扩展为"hello hi world"but "hello,hi,world"

答案3

变量赋值期间不会发生分词,因此ycontains hello,hi,world。但是,分词确实发生在内部[],并且由于您设置了IFS=,它,所以它会扩展为hello hi world单独的单词。

问题是它[需要特定数量的参数,并且它告诉您由于分词而收到了太多参数。由于您用 标记了它bash,因此您可以使用其高级[[ ]]命令来禁用分词,并且不会收到错误。

如果您确实想对 进行分词x,您可以这样做:y="$(IFS=','; echo $x)"。这将hello hi world作为一个单词分配给y.

答案4

您遇到引用问题:

  1. 变量扩展:

    y 将得到字符串 hello hi world

    不,不会。但有回声未引用的将打印这样的值:

    $ IFS=,
    $ x="hello,hi,world"
    $ y=$x
    $ echo $y
    hello hi world
    

    是的,IFS 字符 ( ,) 分割了变量扩展,并且 echo 在参数之间放置了一个空格,详细查看此内容:

    $ printf '<%s>\n' $y
    <hello>
    <hi>
    <world>
    

    然而,引用的扩展不会被 IFS 或 split 改变:

    $ echo "$y"
    hello,hi,world
    $ printf '<%s>\n' "$y"
    <hello,hi,world>
    
  2. 测试线

    [ $x = "hello hi world" ]
    

    同样的引用问题发生在这里,变量被扩展分成单词。该行变为:

    [ hello hi world = "hello hi world" ]
    

    三个参数“hello”、“hi”和“world”无法解析为正确的测试结构。

    然而,这确实:

    $ y=hello,=,world,-o,hello
    $ [ $y = "hello" ] && echo yes || echo no
    yes
    

    因为被执行的是:

    [ hello = world -o hello = "hello" ] && echo yes || echo no
    

    引用可以避免拆分:

    $ y=hello,hi,world
    $ [ "$y" = "hello,hi,world" ] && echo yes || echo no
    yes
    

    由于使用该[[构造也可以避免分裂:

    $ y=hello,hi,world
    $ [[ $y == "hello,hi,world" ]] && echo yes || echo no
    yes
    
  3. 你的问题:

    我对么?

    不,每次变量都以相同的方式扩展。

长话短说

引用你的扩展。

相关内容