【问题标题】:Bash - Running multiple commands using string evaluationBash - 使用字符串评估运行多个命令
【发布时间】:2018-04-27 14:08:19
【问题描述】:

我正在尝试创建一个 shell 脚本,它将多个命令连接到一个字符串,然后执行这些命令。

以下成功(创建 'y' 和 'z' 文件并打印 ls 输出):

$ /bin/touch /z && ls && /bin/touch /y

但以下失败(创建 'y' 和 'z' 文件,还有一个 '&&' 和 'ls' 文件

$ A="/bin/touch /z && ls && /bin/touch /y"
$ $A

似乎通过使用$A 执行该行,二进制touch 将字符串的其余部分作为参数,而&& 运算符未按预期执行。 (我也尝试用;|| 等切换&&,但得到了相同的结果)

我发现 eval $A 可以解决问题,但我仍然很好奇为什么会发生这种情况。 (并且可能想跳过评估​​的需要)

谢谢!

【问题讨论】:

  • && 在变量扩展之前被解释,所以这永远不会起作用。
  • 但是$A 不只是用字符串替换表达式,因此&& 的解释与不使用字符串运行它完全相同?
  • 不,它不是这样工作的,有一个操作顺序。
  • 你必须使用eval,但除非你的目标是编写一个可以执行任意用户输入的程序,否则你应该定义一个shell函数。
  • 这在BashFAQ #50中也有详细介绍。

标签: bash shell string-evaluation


【解决方案1】:

一般来说,评估命令行有两个阶段:解析和扩展。


当你进入

/bin/touch /z && ls && /bin/touch /y

首先将字符串解析为由空格分隔的初步单词系列:

  • /bin/touch
  • /z
  • &&
  • ls
  • &&
  • /bin/touch
  • /y

此时,它会将&&s 识别为分隔由以下单词组成的简单命令列表:

  1. /bin/touch, /z
  2. ls
  3. /bin/touch, /y

现在,它对每个单词应用一组扩展,以尝试生成更多单词。在这种情况下,没有什么可扩展的,并且再次检查每个简单命令以识别命令本身及其参数:

  1. 命令/bin/touch,参数/z
  2. 命令ls,无参数
  3. 命令/bin/touch,参数/y

$A的情况下,解析很简单:初步系列中有一个单词$A。那个词接下来经历扩展;唯一相关的是参数扩展,它产生与第一个示例的解析步骤中识别的相同的单词列表。这里的区别在于 list 会进一步扩展;现在不是识别命令名称及其参数的时候。

  1. 命令/bin/touch,带参数...

    1. /z
    2. &&
    3. ls
    4. &&
    5. /bin/touch
    6. /y

字符串实际上永远不是捆绑一组命令的正确方法。你要做的是定义一个函数

a () {
  /bin/touch /z && ls && /bin/touch /y
}

然后您将其用作普通命令:

$ a
/z
$ ls
/z
/y

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 2013-08-16
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    相关资源
    最近更新 更多