评估作为 bash if 语句的字符串

评估作为 bash if 语句的字符串

我的脚本有一个函数do_command(),可以打印命令然后执行它。我想将命令放入 bash 字符串数组中,然后 print _ 使用此函数执行它们。但是当我用 if 语句尝试这个时,它失败了。这是脚本:

#!/bin/bash

do_command () {
    echo "$@";
    $@;
}

comms=( "wget -O test http://speedtest.ftp.otenet.gr/files/test100k.db" # just a download test \
        "/bin/bash -c 'if [ -f test ]; then mv test test.old; fi'"      # replace previous test \
      );

for comm in "${comms[@]}"; do do_command "$comm"; done

我尝试过单引号+双引号的不同组合,将裸露的 if 语句放在那里或作为 的参数/bin/bash,但尚未找到一种方法来做到这一点。通过这种特定的组合,最后一行的输出为:

/bin/bash -c 'if [ -f test ]; then mv test test.old; fi'
[: -c: line 1: unexpected EOF while looking for matching `''
[: -c: line 2: syntax error: unexpected end of file

但是,如果我将打印的行复制并粘贴到提示符中,它将执行而不会出现错误。

有没有办法从文件/数组中读取 if 语句,然后在脚本中执行它?

答案1

/bin/bash -c 'if [ -f test ]; then mv test test.old; fi'将得到分词(在未引用的 处$@)为/bin/bash, -c, 'if, [, ... 的参数-c,给 Bash 执行的命令是'if。它有一个不平衡的引号,因此会产生语法错误。 (其余的 args 将转到已执行命令的位置参数。)

它也不适用于"$@"引号,因为脚本只有一个参数,因此它全部保留为单个字符串。

看:我们如何运行存储在变量中的命令?

如果你想存储这样的命令,你必须使用以下命令运行它们eval

execute() {
    printf "executing {{ %s }}\n" "$1"
    eval "$1"
}
cmds=("echo foo bar"
      "if true; then echo yes; fi"
      "foo=123; echo \"\$foo\""
      'echo "$(date)"'
      "echo \"what's \$foo now?\""
     )
for c in "${cmds[@]}"; do
    execute "$c"
done

尽管使用复杂的命令,您仍然会遇到常见的引用地狱问题。

您可能会考虑将命令放在函数中,并使用它set -x来打印发生的情况,但输出会有所不同。

相关内容