Shellに組み込まれた `printf`に与える数に制限はありますか?

Shellに組み込まれた `printf`に与える数に制限はありますか?

ユーティリティパラメータリストの/usr/bin/printf長さは、シェルの最大コマンドライン長です(つまり getconf ARG_MAX、私のシステムでは2097152);はい:

# try using a list that's way too long
/usr/bin/printf '%s\n' $(seq $(( $(getconf ARG_MAX) * 2 ))) | tail -1

出力:

bash: /usr/bin/printf: Argument list too long

今日私は聞いたその殻組み込み printfs にはこれらの制限はありません。

printf '%s\n' $(seq $(( $(getconf ARG_MAX) * 2 ))) | tail -1

出力:

4194304

質問:

  1. スキミングはman bash dashこれらの利点をあまり明らかにしないようです。組み込み printf。どこはい文書化されていますか?

  2. する組み込み printfS(例えば bash)には最大パラメータリスト長(文字)があります。では、その長さはいくらですか?

答え1

特定のユーティリティの使用を擁護することは、実際にはマニュアルの責任ではありません。主にしなければならない説明する組み込みユーティリティを使用できます。

外部ユーティリティと比較して組み込みユーティリティを使用することの利点は、主に速度と拡張機能の可用性です(たとえば、printf変数bashを直接作成できますが、-v varname外部プログラムprintfでは決して作成できません)。

外部ユーティリティの実行は、組み込みユーティリティの実行に比べて遅くなります。特にループで頻繁に実行される場合は、さらにそうです。また、ご存知のように、より長い引数のリストも許可します(これは組み込みユーティリティのみをprintf許可するものではありません)。しかし、すべての組み込みユーティリティは)。

組み込みprintfユーティリティのパラメータリストの長さは、プロセス自体のbashリソース制限によって制限されますbash。一部のシステムでは、利用可能なRAMの大部分を使用してコマンドライン引数のリストを作成できることを意味する場合があります。

このようなさまざまな情報を確認できる文書は、

  • ソースbashコード、パラメータのリストが表示されます。printf動的に割り当てられた接続リストであり、いいえ使用execve()実行printf(外部ユーティリティを実行するときにパラメータリストの長さを制限する理由)。

シェルのprintfいいえ組み込みユーティリティはkshOpenBSDシェルです。ユーティリティは大丈夫です障害のある使用bashenable -n printf

答え2

/usr/bin/printfユーティリティパラメータリストの長さは、シェルの最大コマンドライン長に制限されています(例:getconf ARG_MAX、私のシステムでは2097152)。

それじゃないシェルこれらの制限は、むしろオペレーティングシステム(Linuxカーネル)、特にそのexecve(2)システムコールの制限であり、コマンドライン引数と環境変数を起動プログラムに渡す古い方法によるものです。

(この制限には環境変数も含まれます!)

Skimming man bash dashは、組み込みのprintfの利点についてあまり話していないようです。どこに記録されていますか? bashなどのprintfs組み込み機能にパラメータリストの長さがありますか?それでは、その長さは何ですか?

シェル組み込み機能は通過しないため、execve(2)このような制限は必要ありません。最新のシェルは通常、固定サイズのバッファなどを使用しないため、通常、使用可能なメモリ量と仮想アドレス空間のレイアウトによって制限が課されます。つまり、すべての意図と目的に無制限です。

答え3

POSIX標準では、シェルの実装に行制限があってはなりません。

したがって、これはシェルによって文書化されていない自然な現象です。

注:テキストファイルはLINE_MAX行以下のファイルなので、シェルスクリプトはテキストファイルではない可能性があります;-)

関連情報