无法在 bash 变量内运行命令,包括带有 nullglob 的方括号

无法在 bash 变量内运行命令,包括带有 nullglob 的方括号

假设我想在打开 nullglob 的情况下运行存储在变量内的命令。例如:

shopt -s nullglob
a="echo [foo]bar"
${a}

当然,由于 nullglob 选项,这给了我一个空输出,但我想要以下输出(我无法得到):

[foo]bar

我尝试用 \ 转义 [] 但这只给了我:

\[foo\]bar

逃避它的正确方法是什么?

编辑(澄清一些上下文):

我有一个这样的脚本:

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    a="command --option [${base}]foo"
    ${a}
done
shopt -u nullglob

我想要实现的是使用包含 [] 作为普通字符(没有任何匹配)的选项为每个文件运行命令。这里的 nullglob 仅用于 for 循环。

也就是说,如果“tmp”包含“a.pdb”,则运行:

command --option '[a]foo'

如果不存在这样的文件,则什么也没有。

与此同时,我发现将“shopt -u nullglob”移动为 for 循环中的第一个命令似乎可以解决问题。然而,我很好奇即使使用 nullglob 是否也能以某种方式转义 [] 。

答案1

首先,阅读我试图将命令放入变量中,但复杂的情况总是失败!

然后,定义一个函数:

a () {
    echo "[foo]bar"
}

对于您的脚本,没有理由首先将命令放入变量中;只需运行命令即可。

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    command --option "[${base}]foo"
done
shopt -u nullglob

如果你必须将某些内容存储在变量中,将命令与其选项分开,并使用数组来保存选项。

shopt -s nullglob
cmd=command
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    options=( --option "[${base}]foo" )
    "$cmd" "${options[@]}"
done
shopt -u nullglob

答案2

我不明白你为什么将命令保存为变量。为什么不做如下所示的事情来避免这个问题呢?

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    command --option "[${base}]foo"
done
shopt -u nullglob

或者,如果出于其他原因需要在变量中使用该命令,您可以删除该命令nullglob并在运行该命令之前确保文件存在:

for file in tmp/*.pdb; do
  if [ -e "$file" ]; then
        base="$(basename ${file} .pdb)"
        a="command --option [${base}]foo"
        ${a}
done

将命令保存为变量并不是一个好主意。另一种方法是保存选项作为变量:

shopt -s nullglob
for file in tmp/*.pdb; do
    base="$(basename ${file} .pdb)"
    a="--option [${base}]foo"
    command "$a"
done
shopt -u nullglob

相关内容