GNU/Linux >> Linux の 問題 >  >> Linux

引用符で囲まれた文字列と引用符で囲まれていない文字列の拡張?

  1. for i in $(xrandr); do echo "$i" ; done
  2. for i in "$(xrandr)"; do echo "$i"; done
  3. for i in "$(xrandr)"; do echo $i; done

1が2と異なる理由を理解していますが、3が2とは異なる出力を提供するのはなぜですか?出力についても説明してください。引用符は改行でどのように機能しますか?

承認された回答:

引用符で囲まれていない変数($varなど) )またはコマンド置換($(cmd)のように) または`cmd` )は split + glob ボーンのようなシェルの演算子。

つまり、コンテンツは$IFSの現在の値に従って分割されます。 特別な変数(デフォルトではスペース、タブ、改行文字が含まれています)

そして、その分割の結果として生じる各単語は、ファイル名の生成の対象となります。 (グロビングとも呼ばれます またはファイル名の拡張 )、つまり、それらはパターンと見なされ、そのパターンに一致するファイルのリストに展開されます。

したがって、for i in $(xrandr)$(xrandr) 、引用符で囲まれていないため、スペース、タブ、改行文字のシーケンスで分割されます。そして、その分割の結果として生じる各単語は、一致するファイル名についてチェックされ(または、どのファイルとも一致しない場合はそのままになります)、for それらすべてをループします。

for i in "$(xrandr)"コマンド置換としてsplit+glob演算子を使用していません 引用符で囲まれているため、 oneのループには1つのパスがあります 値:xrandrの出力 (コマンド置換の末尾の改行文字なし ストリップ)。

ただし、echo $iでは 、$i 再び引用符で囲まれていないため、$iの内容も 分割され、ファイル名の生成の対象になります そしてそれらは別々の引数としてechoに渡されます コマンド(およびecho 引数をスペースで区切って出力します。

だから教訓:

  • 単語の分割が必要ない場合 またはファイル名の生成 、常に変数の展開とコマンドの置換を引用します
  • 単語分割が必要な場合 またはファイル名の生成 、引用符で囲まないままにしますが、$IFSを設定します それに応じて、および/または必要に応じてファイル名の生成を有効または無効にします(set -fset +f

通常、上記の例では、xrandrの出力で空白で区切られた単語のリストをループする場合 、次のことを行う必要があります:

  • $IFS 空白で分割するには、デフォルト値で(または設定を解除して)
  • set -fを使用します xrandrであることが確実でない限り、ファイル名の生成を無効にします *を出力することはありません または? または[ 文字(ファイル名生成パターンで使用されるワイルドカード)
関連:Db2 – DB2データベースの接続文字列を見つけますか?

次に、inでsplit+glob演算子のみを使用します(コマンド置換または変数展開は引用符で囲まないままにします)。 forの一部 ループ:

set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done

(空でない)をループする場合 xrandrの 出力には、$IFSを設定する必要があります 改行文字へ:

IFS='
'

Linux
  1. 特定の文字列を含むファイルの数は?

  2. 辞書を使用した文字列の置換?

  3. `〜#`はバッシュのチルダ拡張ですか?

  1. Bashスクリプトで文字列を分割する方法

  2. in_addr_t を文字列に

  3. ランダムを使用してbashでランダムな文字列を生成する

  1. system() 関数の文字列の長さ制限

  2. 編集情報

  3. この curl コマンドに変数を追加するにはどうすればよいですか?