nullglobを含む角かっこを含むbash変数内でコマンドを実行することはできません。

nullglobを含む角かっこを含むbash変数内でコマンドを実行することはできません。

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'

そのファイルがなければ何も起こりません。

その間、forループの最初のコマンドとして"shopt -u nullglob"を移動することが効果があることがわかりました。ところで、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

関連情報