はい
x=$y
そして
x="$y"
彼らはいつも同等ですか?これを見つける方法がわからない。これまで私はx="$y"
「安全に遊ぶ」ことに慣れていました。しかし、私はx=$1
明らかに余分な二重引用符が必要ないことを使用して気づきました。
Open Group POSIX ドキュメントの動作はどこで定義されていますか?
答え1
はい、POSIXシェルでも同じであることが保証されていますx=$y
。x="$y"
あなたまたは他のコード読者が二重引用符がどこにあるかわからない場合〜しなければならない使用されます(参照いつ二重引用符が必要ですか?)、二重引用符を含めることは混乱を避けるためにより安全な選択かもしれません。
POSIX仕様では(2.9.1節。 「簡単なコマンド」):
与えられた単純なコマンドを実行する必要がある場合は、[...]次の拡張、割り当て、およびリダイレクトをコマンドテキストの最初から最後まで実行する必要があります。
- 次の規則に従って変数の割り当てまたはリダイレクトによって識別される単語シェル構文規則ステップ3と4の処理のために保存します。
[...]
- リダイレクトは、次の説明に従って実行する必要があります。リダイレクト。
- チルダ拡張、パラメータ拡張、コマンド置換、算術拡張、および引用符の削除を割り当てる前に、すべての変数割り当てを拡張する必要があります。
4番目の項目には次のものは含まれません。フィールド分割またはパス名拡張(「globbing」)、しばしば単語が現れるときに発生する拡張の一部いいえ変数の割り当てとして認識されます。割り当て時にこれらのステップが削除されるため、参照は不要です。
また、見ることができますセクション2.6「単語の拡張」:
単語拡張の順序は次のとおりです。
- チルダ拡張(参照)チルダ拡張)、パラメータ拡張(参照)パラメータ拡張)、コマンドの置き換え(参照コマンドの置き換え)と算術拡張(参照)算術拡張)は最初から最後まで実行する必要があります。項目5を参照トークン認識。
- フィールドの分割(参照フィールド分割)は、nullでない限り、手順1で作成したフィールド部分に対して実行する必要があります
IFS
。- パス名の拡張(参照パス名拡張
set -f
)は、効力が発生しない限り施行されます。- 参照を削除する(参照見積もりの削除)は常に最後に実行する必要があります。
y
以下は、inx=$y
とx="$y"
が実際に特殊引数の1つである場合にのみ重要です。*
@
"$@"
次に拡張されるので参考にしてください。リスト文字列の場合、whatx=$@
とx="$@"
doは指定されていませんが、x=$*
同じですx="$*"
。一部のシェル(たとえば、、bash
)ksh93
では$@
、の最初の文字が空白の場合と同じように使用され、他のシェル(たとえば、busybox、、、)は設定値の最初の文字を使用するのと同じです。$*
$IFS
sh
dash
zsh
$*
$IFS
答え2
一般的に次のようなものがあります。二つ変数を定義できるセクションです。
先行変数の割り当て
ダッシュボードのマニュアルには簡単なコマンドが記載されています。
「name = value」の形式の前の単語が削除されます。
つまり、
x=$y
正確にx="$y"
。つまり、2.9.1節。 「簡単なコマンド」トークン化またはパス名拡張は適用されません。これら2つの拡張子は新しい単語を生成できる唯一の拡張子であるため、IFS文字を含む変数を分割したり、複数のファイル名を一致させることはできません。そこで一言は
x=$y
一言で残るだろう。残りのパラメータ
「コマンド名」を表す単語が見つかると、解析の変更と割り当てが分割され、別のものになる可能性があります。
Bashのマニュアルでは、これを次のように説明します。
代入は、エイリアス、宣言、組版、エクスポート、読み取り専用、およびローカルの組み込みコマンド(宣言コマンド)の引数としても表示できます。
まだ引用すべき場所があります。のように
declare x="$y"
。もちろん、POSIXでは、
export
andだけがreadonly
意味があります。これでyashでのみ失敗します。
$ yash -c 'unset x; y="one two"; readonly x=$y; echo "x=$x"' x=one
はい。通常はx=$y
まったくx="$y"
同じです。とは別に場合によっては、コマンド名の後に変数割り当てが存在します。