linux - “參數列表太長”限制是否適用於shell內置函數?




bash unix (2)

我瀏覽了Stack Overflow上的很多 posts 以及關於 argument list too long 的一些相關社區 argument list too long 主題,我似乎沒有清楚地知道長度限制是否適用於shell內置 argument list too long

假設我想通過標準輸入將一個非常長的字符串傳遞給命令:

string="a very long list of words ..."

我能說......麼:

# not using double quotes around $string is deliberate
printf '%s\n' $string | cmd ...

要么

cmd <<< $string

甚至將它傳遞給 xargs

printf '%s\n' $string | xargs cmd ...

有人可以澄清一下嗎?


我似乎沒有計算長度限制是否適用於shell內置函數。

可能不是,但你應該檢查你的特定版本的 bash 的源代碼(因為它是免費軟件)。 但是,顯然有一些 - 更大的限制(特別是因為在 bash 完成的一些 malloc 可能會失敗),但是你會得到另一個錯誤消息或行為。

AFAIK,參數列表太長錯誤由 execve(2) 給出了 E2BIG 失敗,而bash的內置函數沒有 fork 然後 execve (就像命令調用外部程序那樣)。

在實踐中, E2BIG 可能會出現幾十萬字節(確切的限制取決於內核和系統),但我想內置可以使用幾十兆字節(在今天的桌面上)。 但是YMMV(因為你可以使用 ulimit 讓你的shell做一些 setrlimit(2) ......)。 我不建議通過shell內置處理千兆字節的數據。

順便說一句, xargs(1) 可能會有所幫助,您甚至可以通過重新編譯內核來提高限制(對於 E2BIG )(在最近的內核中也可以通過其他方式)。 幾年前,這是我重新編譯內核的強烈動機。


在bash中,操作系統對命令行長度的強制限制導致錯誤 argument list too long ,不適用於shell builtins。

execve() 系統調用返回錯誤代碼 E2BIG 時會觸發此錯誤。 調用內置函數時不涉及 execve() 調用,因此無法發生錯誤。

因此,你提出的兩個操作都是安全的: cmd <<< "$string"$string 寫入一個臨時文件,它不要求它作為argv元素傳遞(或者一個環境變量,它存儲在同一個文件中)預留空間池); 並且 printf '%s\n' "$cmd" 發生在shell內部,除非shell的配置已經被修改,就像 enable -n printf ,以使用外部 printf 實現。





command-line-arguments