2

我想在 bash 中传递部分命令,以便:

commandpart=( --flags "filename" >/dev/null )
command "${commandpart[@]}"

将评估为:

command --flags "filename" >/dev/null

这以前对我很有用,不幸的是,将 a>放入 bash 数组会导致语法错误。

意外标记 `>'
`commandpart=( --flags "filename" >/dev/null )'附近的语法错误

我尝试过的其他事情是将它全部粘贴到一个字符串中并eval对其进行 ing:

commandpart="--flags filename >/dev/null"
eval "command $commandpart"

但这会带来转义、空格等问题。(而且 eval 并不是最佳实践)

最好,如何在不转义字符的情况下修复第一个示例中的语法错误<>&?我想继续使用这种数组语法,因为它似乎比 eval 更健壮并且不需要转义。

如果没有,是否有另一种方法可以满足我的需要来移动部分命令?

加分点:如果我将参数传递给要执行的脚本,如下所示:

#!/bin/bash
echo "script running"
command "${@}"

我有一个新问题,将其添加 >/dev/null到脚本调用将其应用于脚本,而不是命令:

$ script >/dev/null

转义时将其应用于命令,但作为没有预期效果的字符串。(例如,如果命令是 firefox,它会在名为 '>/dev/null' 的页面上打开 firefox 并立即 404)

4

2 回答 2

4

来自 bash(1):

一个简单的命令是一系列可选的变量赋值,后跟空格分隔的单词和重定向,并由控制操作符终止。第一个字指定要执行的命令,并作为参数零传递。剩余的单词作为参数传递给调用的命令。

这意味着重定向不是命令行的一部分。它们被 bash 解释为命令将在其中运行的“环境”描述的一部分,与分配它之前的环境变量相同。

从同一个 bash(1):

将其拆分为单词后在命令行上执行扩展。

这暗示了这样一个事实,即在时间参数扩展(在您的情况下为“${commandpart[@]}”)发生时,单词已经与重定向分开。由于这不太可能发生两次,这意味着参数扩展的结果不会被解释为重定向。

您可以通过创建一个函数来引用不是重定向的数组元素,遵循 bash 引用规则,然后将它们作为参数传递给 eval 来完成这项工作。但是,该函数必须能够像 bash 一样区分重定向和“单词”,而且种类很多。这也可能需要引用某些重定向的部分内容。

我建议不要存储/传递重定向,而是根据需要应用它们来代替调用。如果您总是需要使用某些命令进行重定向,请制作包装函数或脚本。

于 2013-05-05T11:23:29.160 回答
2

您会想阅读我正在尝试将命令放入变量中,但复杂的情况总是失败!关于为什么这是一个问题,并且不会真正按照您想要的方式工作。

于 2013-05-05T11:13:20.350 回答