噴射とは何ですか?シェルプログラミングでは、なぜこれが重要なのでしょうか?

噴射とは何ですか?シェルプログラミングでは、なぜこれが重要なのでしょうか?

で噴射の役割が混乱していますzsh。私はC、Python、またはMATLABでプログラミングしている間、この概念に触れたことがなかったので、単語分割がシェルプログラミングに固有のように見える理由に興味がありました。

以前はこのサイトとは異なるサイトで単語の分割について読みましたが、概念の明確な説明が見つかりませんでした。ウィキペディアには一つあります。噴射の定義しかし、これがUnixシェルにどのように適用されるかについての言及はないようです。

私の混乱の例は次のとおりですzsh

内部にZシェルのよくある質問、私は以下を読んだ。

3.1:なぜ私の期待に満たない$var場所がありますか?var="foo bar"

ほとんどのBourne-shell派生項目では、マルチワード変数(たとえば)は、 var="foo bar" コマンドに渡されるかループで使用されるときに単語に分割されますfor foo in $var。デフォルトでは、zshにはこれらの動作はありません。変数は変更されていません。 (これはエラーではありません!以下を参照してください。)このオプションはSH_WORD_SPLIT互換性のために存在します。

しかし、Z Shell マニュアルで、私は以下を読んだ。

SH_WORD_SPLIT (-y) <K> <S>

引用符なしのパラメータ拡張では、フィールド分割が実行されます。このオプションに注意してください何もしない 噴射で。 (パラメータの拡張を参照してください。)

SH_WORD_SPLITなぜあるというの?何もしない噴射で?これは噴射ではありませんか?

ベストアンサー1

初期シェルには、文字列という単一のデータ型しかありませんでした。しかし、通常、複数のファイル名をプログラムに引数として渡すときに文字列リストを操作するのは非常に一般的です。分割のもう一つの一般的なユースケースは、コマンドが結果リストを出力する場合です。コマンドの出力は文字列ですが、必要なデータは文字列のリストです。変数にファイル名のリストを保存するには、名前の間にスペースを追加します。その後、このようなシェルスクリプト

files="foo bar qux"
myprogram $files

myprogramシェルが文字列を単語に分割すると、$files3つの引数で呼び出されます。当時、ファイル名の空白は禁止されているか、未完成と広く考えられていました。

これコーエンシェル配列の紹介:文字列のリストを変数に保存できます。 Kornシェルは当時確立されたBourneシェルとまだ互換性があるため、デフォルトの変数拡張は継続的なトークン化を実行し、配列を使用するにはわずかな構文オーバーヘッドが必要です。上記のスニペットを作成できます。

files=(foo bar qux)
myprogram "${files[@]}"

Zshは最初から配列を持っており、作者は以前のバージョンとの互換性を犠牲にしてより合理的な言語デザインを選択しました。 zshでは(デフォルトの拡張規則に従って)$var単語の分離は行われません。単語リストを変数に保存するには、配列を使用する必要があります$=var

files=(foo bar qux)
myprogram $files

ファイル名の空白は、最近扱うべき問題です。これは、多くのユーザーが空白が機能することを期待し、攻撃者が潜在的にファイル名を制御できるセキュリティに敏感なコンテキストで多くのスクリプトが実行されるためです。したがって、単語の自動分離はしばしば問題になります。したがって、一般的なアドバイスは、"$foo"特定のユースケースで単語の分離が必要な理由を理解していない限り、常に二重引用符を使用することです。 (基本変数の拡張にもワイルドカードが発生することに注意してください。)

私の答えでは、私は「スプレー」という言葉を使いました。変数を設定して単語(フィールドとも呼ばれる)の構成を構成できるため、これを「フィールド分割」ともいいますIFS。単語内のすべての文字はIFS単語区切り文字と見なされ、単語は単語ではなく一連の文字です。分離記号。IFSデフォルトでは、デフォルトの空白文字が含まれます(キャリッジリターン、分割できないスペースなどではなく、ASCIIスペース、タブ、および改行)。zshマニュアルでは、「単語の分離」はシェルコードの解析手順を参照するためにのみ使用され、変数とコマンドの置換後に発生する拡張の一部であるフィールド/単語の分割とは関係ありません。

おすすめ記事