出力を変数に代入するときにコマンド置換を引用する必要がありますか? [コピー]

出力を変数に代入するときにコマンド置換を引用する必要がありますか? [コピー]

出力が変数に割り当てられても、次のようにコマンド置換を引用する傾向があります。

var="$(command)"

しかし、これは本当に必要ですか?いつ壊れるの?受け入れられた回答ここ主張する:

DIRNAME="$(ディレクトリ名$FILE)"欲しいことはしない$FILE の空白またはワイルドカード文字 [?*。

このリンクはGrey Cat Wikiの引用に関する素晴らしいページにリンクされていますが、そのページでは引用コマンドの置き換えについて特に言及していません。そして引用しながら変える明らかに必要ですが、quoteコマンドの置き換え自体は必要ないようです。

しかし、同じ記事では、次のように結論を下しました。

DIRNAME="$(dirname "$FILE")" が推奨される方法です。他のものを変更せずにDIRNAME =をコマンドとスペースに置き換えることができ、dirnameは正しい文字列を受け取ります。

これは私がいつも考えてきたもので、ここで言及されていない投稿をしばしば修正することです。ただし、上記のWikiページには次のような主張もあります。

場合によっては、二重引用符を安全に省略できます。

単純課題の右側にあります。引用符なしでfoo = $ barを書くことができます。これはPOSIXと互換性があります。

[。 。 。 ]

これは実際には「簡単な」割り当てではありませんが、var=$(command)実際に引用が必要な場合はまだ見つかりません。

$ var=$(echo "foo bar baz")  ## whitespace works
$  echo "$var"
foo bar baz

$ var=$(printf "foo\nbar * baz") ## so do globbing characters
$ echo "$var"
foo
bar * baz

$ var1="foo\nbar * baz"
$ var=$(printf "$var1")  ## printing a variable doesn't make any difference
$ echo "$var" 
foo
bar * baz

$ var=$(printf '%s\n' "$var1")
$ echo "$var"
foo\nbar * baz

$ var=$(printf -- '-e %s\n' "$var1") ## strings starting with - also work
$ echo "$var"
-e foo\nbar * baz

もちろん、そのようなものに直接コマンド置換を使用するなら引用command1 "$(command2)"符は必ず必要ですが、変数に割り当てるときにはそうではありません。

それでは、私が何を見逃しているのでしょうか?見積もりが必要ですか?どの特別なケースがコマンド置換を呼び出すのですか?戻り値を変数に割り当てるときあなたを保護しますか?あるいは、コマンド置換が変数代入操作の右側である場合、コマンド置換を引用しなくても常に大丈夫ですか?

ベストアンサー1

あなたはそうです不要代入文の右側の式を参照します。

あなたをいじめるのは別の答えですおすすめそれにもかかわらず。しかし、これはコードメンテナンスに関するものです。

以下を考慮してください正しい例:

DIRNAME=$(dirname "$FILE")
echo "debug: dirname is $DIRNAME"
ls "$DIRNAME"

このスクリプトをしばらく使用したら、デバッグメッセージを削除できると思います。したがって、エディタを使用するとエコーラインを削除できます。これにより、DIRNAME変数が不要になることがわかります。ls割り当てられた左側のサイトを置き換えるコマンドを移動するだけです。今できる必要な引用符を追加するのを忘れました。君はこれで終わるんだ壊れたスクリプト:

ls $(dirname "$FILE")

最初の作成者がシェルの専門家であり、2番目の編集者が初心者の場合、これらのエラーが発生する可能性が高くなります。

もちろんこれが議論の余地があるのか​​?ポータブルシェル機能を使用しないことをお勧めします。本当に便利です。個人的に私は主に彼のアドバイスに従います。また、次のように、より簡単な割り当てのためにこれを行います。 (var="${foo}"追加の中括弧も含みます。)

おすすめ記事