for i in $(xrandr); do echo "$i" ; done
for i in "$(xrandr)"; do echo "$i"; done
for i in "$(xrandr)"; do echo $i; done
1が2と異なる理由を理解しています。しかし、なぜ3は2とは異なる出力を提供しますか?出力についても説明してください。改行の周りの引用符はどのように機能しますか?
ベストアンサー1
引用符のない変数(例:)$var
またはコマンドの代入(例:$(cmd)
または`cmd`
)は次のとおりです。分割+グローバルBourne シェルに似た演算子です。
つまり、その内容は$IFS
特殊変数(デフォルトではスペース、タブ、および改行を含む)の現在の値に基づいて分割されます。
その後、分割によって生成された各単語ファイル名の生成(また〜として知られているワイルドカードまたはファイル名拡張子)、つまりパターンとして処理され、そのパターンに一致するファイルのリストに展開されます。
したがって、for i in $(xrandr)
は$(xrandr)
引用符の内側にないため、一連のスペース、タブ、および改行に分割されます。そして、その分割で生成された各単語がファイル名と一致することを確認し(またはファイルと一致しない場合はそのままにしてください)、for
繰り返します。
ではfor i in "$(xrandr)"
分割+グローブ演算子を使用しません。コマンドの置き換え参照されるので、ループで一度一つxrandr
値:(末尾の改行なしで出力コマンドの置き換え巻)。
ただし、再びecho $i
参照されないため、$i
コンテンツは$i
再分割され、次に従います。ファイル名の生成これは別の引数としてコマンドに渡されますecho
(echo
スペースで区切られた引数は出力されます)。
だから得た教訓は次のとおりです。
- 欲しくないなら噴射またはファイル名の生成、常に変数の拡張とコマンドの置換を参照してください。
- 本当に欲しいなら噴射またはファイル名の生成、引用符なしでそのままにして、
$IFS
適切に設定するか、必要に応じてファイル名の生成を有効または無効にします(set -f
、、set +f
)。
通常、上記の例では、出力でスペースで区切られた単語のリストを繰り返すには、xrandr
次のものが必要です。
$IFS
スペースに分割するには、デフォルト値(または設定しない)をそのままにします。- または、文字が出力されないと
set -f
確信しない限り、ファイル名の生成を無効にするために使用されます(これはファイル名生成モードで使用されるワイルドカードです)。xrandr
*
?
[
in
次に、ループ部分で分割+glob演算子を使用します(引用符なしでコマンド置換または変数拡張のみを残します)for
。
set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done
繰り返したい場合(空ではない)ワイヤー出力するには改行文字にxrandr
設定する必要があります$IFS
。
IFS='
'