IFSのデフォルト値を理解する


10

私のGNU bashバージョン4.2.8では、IFSにはデフォルトでスペース、タブ、およびラインフィードのデフォルト値があります。

usr@T42 ~ $ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
00000003
usr@T42 ~ $ 

そのようなデフォルトのIFSには理由がありますか?さらに、bashビルトインの他にどのユーティリティがIFSを使用しreadますか?

回答:


13

IFS変数は、シェルがワード分割と呼ばれるタスクを実行するたびに使用されます。これが使用される最も一般的なケースは$var、コマンド内のパラメーター展開(例$(some-command):)またはコマンド置換(例:または非推奨のバックティック)の後です。ここで、展開にIFS文字が含まれている場合、コマンドが処理される前に、異なる「単語」に分割されます。事実上、これはこれらの文字が置換されたテキストを異なる引数に分割することを意味します(変数が最初に指定されている場合はコマンドの名前を含みます)。

したがって、デフォルト値IFSがスペース、タブ、および改行である理由は、これらが通常は単語を分割すると予想される空白文字であるためです。

単語の分割が起こらないようにする1つの方法は、展開("$var")の前後に二重引用符を使用することです。実際、これは質問で行っています。これを行わなかった場合echoは、引数がなく、文字だけが引数を分割するため、出力はありません。

また、パラメータ展開後に単語分割が行われない 2つの場所は、変数の割り当て(たとえばvar=$othervar、and var=$(somecommand)ok)と構成内[[ ]][[ $var = $othervar ]]okですが、[ $var = $othervar ]引用符で囲む必要があります)にあります。

最後に、賢明な人が私に一度指摘したように、一般的な誤解は、単語分割の防止が変数を引用する唯一の理由であるということです。それはそうではありません。より一般的に知られているように、引用パス名の展開グロブの展開も防ぎます。変数に*このようなグロブ文字が含まれている場合、変数をコマンドで引用符なしで使用すると、これらはファイル名に展開される可能性があります。たとえば、次のことを考慮してください。

var=*
echo $var

現在のディレクトリにあるファイルの名前が表示されます。

以下のようステファンは、以下の指摘、内の文字の順序がIFS拡大する際に重要です"$*"bashmanページから:

"$*" is equivalent to "$1c$2c...", where c is the first character of the value of
the IFS variable.  If IFS is unset, the parameters are separated by spaces.  If
IFS is null, the parameters are joined without intervening separators.

単語分割のその他の例については、この回答を参照してください-https://unix.stackexchange.com/a/118444/48083


1
の最初の文字$IFSも使用され"$*"ているため、順序が重要になります。
ステファンChazelas

2
またzsh、デフォルトにNUL文字が含まれていることにも注意してください$IFS(他のシェルは、変数にNUL文字を保持することをサポートしていません)。
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.