ここで出口が必要ない理由は何ですか?

ここで出口が必要ない理由は何ですか?
$ IFS=";"

$ read first second 
i am;a_i b c
$ echo $first
i am
$ echo $second
a_i b c

$ echo $IFS
  1. 私の言葉は正しいですか?これはread first second現在のシェルプロセスの子プロセスですか?それではなぜ必要ないのですかexport IFS=";"
  2. なぜ空ですかIFS

答え1

私の言葉は正しいですか?読んだ最初の瞬間は、現在のシェルプロセスの子プロセスですか?それでは、IFS = ";"をエクスポートする必要がないのはなぜですか?

read一つでもないバッシュ組み込み関数。ここでは、サブシェルやサブプロセスは作成されませんIFS

IFSが空の理由は何ですか?

二重引用符を使用しなかったためです。 IFS値をに変更したので、拡張すると、;シェルecho $IFSは単語分割とワイルドカードを実行するための区切り文字として使用されます。これで何も印刷されません。$IFS;;

努力する:

$ IFS=";"
$ printf "%s\n" $IFS

$ printf "%s\n" "$IFS"
;

ノート

答え2

入力するとtype read取得しますread is a shell builtin。したがって、子プロセスとして実行されません。

答え3

IFSが空である理由に答えてください。そうではありません。しかし、その値はIFSシェルの動作を変更することです。以下は説明ではなく、Debian Gnu + Linuxでbashを使用した実験の結果です。

a=";"; echo $a生産する;

IFS=";"; echo $IFS空行を生成します。 IFS=";"; echo "$IFS"生産する;

a=";"; echo $a空の行が生成されますが、IFS=" "; a=";"; echo $a再び;

だから

IFS=";"; a=";"; echo $a空の行を生成IFS=" "; a=";"; echo $aします;が。

したがって、IFS値は動作を変更します(エコーに引用符を使用しません)。

答え4

IFS=\;; set -- $IFS; echo $#; echo "$*"

1
;

IFS=; set -- $IFS; echo $#; echo "$*"

0
#there doesn't seem to be anything here

ご覧のとおり、最初の$IFSケースでは空ではなく、フィールド区切り文字のみが含まれています。

シェルが引用符で囲まれていない変数を展開するときに定義された区切り文字に従って値を分割します$IFS。これにより、各変数を$IFS別々の配列にすることができます。デフォルトでは、$IFSa <space>\tab、\newlineに設定されています。これらのそれぞれは特別な$IFS特性を持っています。$IFSスペース$IFSスペース区切り文字は保持されず、シェルがトークン化を実行すると、すべてのシーケンスは単一のフィールドに切り捨てられ、他のすべてのシーケンスには区切り文字ごとに1つのフィールドがあります。$IFSスペースまた、フィールドの開始または終了から完全に削除されます。たとえば、

IFS=/; slashes=///////; printf '<%s>' $slashes
<><><><><><><>

IFS=' '; spaces='      '; printf '<%s>' $spaces
<>

printf '<%s>' $spaces$slashes
<///////>

しかし、$IFSスペース確かにいいえ削除されるといいえ存在する$IFS

IFS=/; printf '<%s>' $spaces$slashes
<      ><><><><><><>

関連情報