History

系統配置“變數”ARG_MAX 的 Linux 實現是否與其他系統變數不同,是否符合 POSIX?

  • January 23, 2014

在 shell 中,正如這個 Q&A在擴展上下文中所解釋的,根據系統,命令參數的最大長度最初受核心設置的限制。最大值在執行時使用getconf命令顯示(另見IEEE Std 1003.1, 2013 Edition):

# getconf ARG_MAX
2097152
vs. value found in limits.h on my setup:
#define ARG_MAX       131072    /* # bytes of args + environ for exec() */

確實:

sysconf() 呼叫提供了一個值,該值對應於程序編譯或執行時的條件,具體取決於實現;對 getconf 的 system() 呼叫始終提供與程序執行時的條件相對應的值。

手冊頁引用了 POSIX,從暗示POSIX 程序員手冊的序言到描述本身:

每個配置變數的值應被確定為好像它是通過呼叫定義為可用的函式獲得的一樣,該函式由本卷 POSIX.1-2008 或由 POSIX.1-2008 的系統介面卷(參見操作數部分)。該值應反映目前執行環境中的條件。

可以查詢的基本變數出現在函式規範表中,並且在標題文件sysconf中有關於值的更多資訊:limits.h

{ARG_MAX}
   Maximum length of argument to the exec functions including environment data.
   Minimum Acceptable Value: {_POSIX_ARG_MAX}
...(nb you cannot be POSIX compliant under a certain value...)
{_POSIX_ARG_MAX}
   Maximum length of argument to the exec functions including environment data.
   Value: 4 096

xargs --show-limits命令證實了其中的一些:

Your environment variables take up 3134 bytes
POSIX upper limit on argument length (this system): 2091970
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2088836
Size of command buffer we are actually using: 131072

sysconf最初設計用於查找 PATH 變數的系統值,然後將其擴展到其他變數。現在,Open Group文件探討了擁有這樣一個框架的基本原理,應用程序可以在執行時輪詢系統變數,以及有關基線的相關實際考慮……:

(…) 如果僅限於標題中最嚴格的值,則此類應用程序必須準備好接受最小的微型電腦提供的最有限的環境。儘管這是完全可移植的,但人們一致認為他們應該能夠利用大型系統提供的設施,而不受與源和對象分佈相關的限制。

在討論這個特性的過程中,有人指出,應用程序幾乎總是可以通過適當地測試各種函式本身來辨別執行時的值可能是什麼。而且,無論如何,它總是可以被編寫為充分處理來自各種函式的錯誤返回。最後,人們認為這給應用程序開發人員帶來了不合理的複雜性和復雜性。

…以及這種設置的缺點,因為它與一些文件變數有關fpathconf

pathconf() 函式是在 sysconf() 函式之後立即提出的,當時人們意識到某些可配置值可能在文件系統、目錄或設備邊界之間有所不同。

例如,{NAME_MAX} 在 System V 和基於 BSD 的文件系統之間頻繁變化;System V 最多使用 14 個,BSD 255。在提供兩種文件系統類型的實現中,應用程序將被迫將所有路徑名組件限制為 14 個字節,因為這將是在此類系統中指定的值。

因此,其目的是減輕開發人員對基線的一些負擔,同時承認文件系統的多樣性,並通常允許對平台的不同變體進行一些定制。硬體、 Unix和相關標準(C 和 POSIX)的演變在這裡發揮了作用。

問題:

  • 該命令getconf沒有“列表”選項,並且set,printenvexport不顯示這些變數。是否有列出其值的命令?

  • 為什麼像這樣的設施fpathconf似乎是為了引入更多的靈活性而建構的,但僅適用於 PATH 和文件相關的系統變數?僅僅是因為當時 getconf 只是關於 PATH 嗎?

  • 目前的 Linux實現是什麼,它是否符合 POSIX?在連結的 Q中,參考 ARG_MAX 的答案隨堆棧大小而變化(“在 Linux 3.11 上……堆棧大小限制的四分之一,如果小於 512kiB,則為 128kiB”):

    • 這樣做的理由是什麼?
    • 這個選擇(堆棧大小的 1/4)是特定於 Linux 的實現,還是只是基本實現之上的一個特性,還是歷史上的 UNIX 實現總是基本上產生堆棧大小的 1/4?
    • 除了 ARG_MAX 之外的許多其他變數是否是堆棧大小或類似資源的函式,或者該變數的重要性是否需要特殊處理?
    • limits.h實際上,是否提供了符合 POSIX 的 Linux 系統/解決方案,並且存在堆棧大小限制的配置,例如,如果某些應用程序隨硬體擴展,或者是直接定制和編譯的一種做法,則允許它超出基本的最大規格滿足特定需求?
    • ARG_MAXlimits.h之類的東西在執行時使用命令與在執行時更改變數ulimit -s與讓核心直接管理它有什麼區別?特別是limits.h由於核心更改,我在 Linux 上已過時的該變數的(低)值,即它是否已被取代?
  • 命令行應該具有與擴展和 ARG_MAX 無關的 shell 特定長度限制;他們在什麼地方bash

沒有標準方法可以檢索系統支持的配置變數列表。如果您為給定的 POSIX 版本程式,那麼該版本的 POSIX 規範中的列表就是您的參考列表。在 Linux 上,getconf -a列出所有可用變數。

fpathconf不特定於 PATH。它是關於與文件相關的變數,這些變數可能因文件而異。

關於ARG_MAX在 Linux 上,取決於堆棧大小的基本原理是參數最終在堆棧上,因此最好有足夠的空間容納它們以及必須適合的所有其他內容。大多數其他實現(包括舊版本的 Linux)具有固定大小。

大多數限制與資源可用性一起使用,根據限制使用不同的資源。OPEN_MAX例如,如果系統沒有可用於文件相關數據的記憶體,則程序可能無法打開文件,即使它打開的文件少於該文件。

預設情況下,Linux 在這一點上是 POSIX 兼容的,所以我不知道你在哪裡。

如果您使用ulimit -s將堆棧大小限制為小於ARG_MAX,則使系統不再兼容。通常可以通過多種方式使 POSIX 系統不兼容,包括PATH=/nowhere(使所有標準實用程序不可用)或rm -rf /.

ARG_MAXin的值limits.h提供了應用程序可以依賴的最小值。execve即使參數超過該大小,也允許符合 POSIX 的系統成功。相關的保證ARG_MAX是,如果參數適合該大小,則execve不會因E2BIG.

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