这两件事有什么区别?

时间:2019-02-03 00:07:50

标签: linux bash eval brace-expansion

我只是想知道两者之间有什么区别?

echo {$number1..$number2}

AND

eval echo {$number1..$number2}

当然,假设$ number1和$ number2中都有一个值。 使用第一个选项只是不起作用,但是使用第二个选项则可以。我不是只希望工作的典型人,我想了解为什么会这样发生,为什么会这样发生?

2 个答案:

答案 0 :(得分:9)

为什么第一个表达式不能按预期工作

  1. 括号扩展在变量扩展之前执行。 $number1..$number2不是有效的序列表达式,因此整个表达式保持不变。
  2. 此后,发生变量扩展,产生表达式{1..3}(假设number1=1number2=3)。

第二个表达式为什么这么做

您的第二个示例的工作原理相同,只是变量扩展({1..3})的结果通过eval再次传递给Bash,这使括号扩展有第二次机会:1..3是一个正确形成的序列表达式,因此大括号扩展会产生预期的结果:

1 2 3

避免使用eval

通常应避免使用eval,因为它很容易引起安全问题:如果number1number2收到输入并且未正确清理,则可以将恶意代码注入到您的程序中。有关在各种使用案例中替换eval的方法,请参见this related question

在您的特定示例中,该序列可以由for循环与算术评估结合来创建:

for ((i=number1 ; i<=number2; i+=1)); do echo -n "$i" ; done | xargs
1 2 3

一种流行的非Bash解决方案是像seq一样使用seq "$number1" "$number2" | xargshis answer的Walter A指出)。

注意:在这些示例中,xargs将多行输出连接到一行。

其他信息

answer to a related question提供了有关该主题的更多信息。

此外,EXPANSION section中的bash(1) manual page对于不同扩展机制的顺序和工作情况也很有帮助。

答案 1 :(得分:0)

变量的替换要晚了。
您可以使用{p>来避免eval

seq -s " " "$number1" "$number2"