ユーティリティパラメータリストの/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
今日私は聞いたその殻組み込み printf
s にはこれらの制限はありません。
printf '%s\n' $(seq $(( $(getconf ARG_MAX) * 2 ))) | tail -1
出力:
4194304
質問:
スキミングは
man bash dash
これらの利点をあまり明らかにしないようです。組み込みprintf
。どこはい文書化されていますか?する組み込み
printf
S(例えばbash
)には最大パラメータリスト長(文字)があります。では、その長さはいくらですか?
答え1
特定のユーティリティの使用を擁護することは、実際にはマニュアルの責任ではありません。主にしなければならない説明する組み込みユーティリティを使用できます。
外部ユーティリティと比較して組み込みユーティリティを使用することの利点は、主に速度と拡張機能の可用性です(たとえば、printf
変数bash
を直接作成できますが、-v varname
外部プログラムprintf
では決して作成できません)。
外部ユーティリティの実行は、組み込みユーティリティの実行に比べて遅くなります。特にループで頻繁に実行される場合は、さらにそうです。また、ご存知のように、より長い引数のリストも許可します(これは組み込みユーティリティのみをprintf
許可するものではありません)。しかし、すべての組み込みユーティリティは)。
組み込みprintf
ユーティリティのパラメータリストの長さは、プロセス自体のbash
リソース制限によって制限されますbash
。一部のシステムでは、利用可能なRAMの大部分を使用してコマンドライン引数のリストを作成できることを意味する場合があります。
このようなさまざまな情報を確認できる文書は、
- ソース
bash
コード、パラメータのリストが表示されます。printf
動的に割り当てられた接続リストであり、いいえ使用execve()
実行printf
(外部ユーティリティを実行するときにパラメータリストの長さを制限する理由)。
シェルのprintf
例いいえ組み込みユーティリティはksh
OpenBSDシェルです。ユーティリティは大丈夫です障害のある使用bash
。enable -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行以下のファイルなので、シェルスクリプトはテキストファイルではない可能性があります;-)