这两件事有什么区别?

Adr*_*llo 6 linux bash eval brace-expansion

我只是想知道它们之间有什么区别:

echo {$number1..$number2}

eval echo {$number1..$number2}

当然,假设$ number1和$ number2中有一个值.第一个选项不起作用,但第二个选项可行.我不是那种只想要工作的典型人,我想知道为什么会这样发生,为什么会发生这样的事情呢?

Mic*_*ros 9

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

  1. 在可变扩展之前执行支撑扩展.$number1..$number2不是有效的序列表达式,因此整个表达式保持不变.
  2. 之后,发生变量扩展,从而产生表达式{1..3}(给定number1=1number2=3).

为什么第二个表达式呢

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

1 2 3
Run Code Online (Sandbox Code Playgroud)

避免使用 eval

使用eval一般应避免,因为它很容易带来安全问题:如果number1number2接收输入,并且没有正确消毒,恶意代码可以被注入到你的程序.有关在各种用例中替换的方法,请参阅此相关问题eval.

在您的具体示例中,序列可以通过for循环结合算术评估来创建:

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

一个流行的非Bash解决方案就是使用seq(正如Walter A在他的回答中指出的那样)seq "$number1" "$number2" | xargs.

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

更多的信息

回答一个相关的问题提供了有关主题的更多信息.

另外,膨胀部bash的(1)手册页是在序列和不同的膨胀机构运作相当丰富.