Bash

命令行長度限制:內置 vs 可執行

  • May 16, 2017

因此,根據POSIX 規範,我們對 有以下定義*

擴展到位置參數,從一個開始,最初為每個設置的位置參數生成一個欄位。當擴展發生在將執行欄位拆分的上下文中時,可以丟棄任何空欄位,並且每個非空欄位都應按照欄位拆分中的描述進一步拆分。當擴展發生在不執行欄位拆分的上下文中時,如果 IFS 包含至少一個字元,則初始欄位應連接以形成單個欄位,每個參數的值由 IFS 變數的第一個字元分隔,或如果 IFS 未設置,則由 a 分隔,如果 IFS 設置為空字元串,則不分隔。

對於絕大多數人來說,我們都知道著名的ARG_MAX限制:

$ getconf ARG_MAX
2621440

這可能導致:

$ cat * | sort -u > /tmp/bla.txt
-bash: /bin/cat: Argument list too long

謝天謝地背後的好人bash

$$ include all POSIX-like others $$) 為我們提供printf了內置功能,因此我們可以簡單地:

printf '%s\0' * | sort -u --files0-from=- > /tmp/bla.txt

一切對使用者來說都是透明的。

ARG_MAX有人可以讓我知道為什麼使用命令繞過限制是如此微不足道,built-in以及為什麼很難提供符合標準的 POSIX shell 解釋器來優雅地處理*獨立執行檔的特殊參數:

$ cat *

那會破壞什麼嗎?我不是要求bash人們cat作為內置提供,我只對操作順序以及為什麼*根據命令是內置的還是獨立的執行檔而以不同的行為進行擴展感興趣。

限制不在外殼中,而在exec()函式族中。

POSIX 標準對此表示

新程序的組合參數和環境列表可用的字節數為{ARG_MAX}. 這個總數中是否包括空終止符、指針和/或任何對齊字節是由實現定義的。

要執行內置於 shell 中的實用程序,shell 不需要呼叫exec(),因此它不受此限制的影響。

還要注意,受限制的不僅僅是命令行的長度,而是命令長度、其參數以及目前環境變數及其值的組合。

另請注意,這不是printfeg中的內置實用程序(恰好充當OpenBSD並在 OpenBSD 上執行)。依賴它作為內置將需要考慮正在使用的特定外殼。pdksh``sh``ksh

引用自:https://unix.stackexchange.com/questions/365336