执行从包含带空格的参数的字符串解析的命令

时间:2014-07-16 11:52:40

标签: bash

我想执行一个由变量(本例中为变量cmd)给出的命令:

cmd="echo 'First argument'"
$cmd

预期结果将是:

First argument

但......实际结果是:

'First argument'

什么?我不明白为什么我可以在输出中看到单引号。毕竟,如果命令(=变量$ cmd的内容)将直接发出,那么没有引号泄漏到输出中,它的行为符合要求:

$ echo 'First argument'
First argument

为了说明我在现实生活中想要实现的目标:在我的部署脚本中有一个像这样的代码块(强烈简化,但你明白了):

#!/bin/bash
function execute {
    cmd=$1
    echo "Executing $cmd ..."

    # execute the command:
    $cmd
}    

VERSION=1.0.2
execute "git tag -a 'release-$VERSION'"

现在,Git会创建一个包含单引号的标记:

git tag
'1.0.2'

这不是我想要的......

怎么办?

(Bash版:GNU bash 3.1.0)

(我发现了一个非常类似的问题here,但答案不适用于我的问题)

2 个答案:

答案 0 :(得分:3)

cmd="echo 'First argument'"
$cmd

会发生分词,实际结果命令是:

echo "'First" "argument'"

使用单引号进行双重解析永远不会发生。

此外,最好使用数组:

#!/bin/bash

function execute {
    cmd=("$@")  ## $@ is already similar to an array and storing it to another is just optional.
    echo "Executing ${cmd[*]} ..."

    # execute the command:
    "${cmd[@]}"
}    

VERSION=1.0.2
execute git tag -a "release-$VERSION"

在这种情况下,eval是一个艰难的选择。您可能不仅会获得意外的解析结果,还会意外地运行危险的命令。

答案 1 :(得分:1)

我认为这就是你想要的:

cmd="echo 'First arg'"
eval $cmd
First arg