2010-02-09 47 views
7

我有一個Perl腳本,它執行各種安裝步驟來爲我們公司設置開發框。它運行各種shell腳本,其中一些腳本由於低於所需的ulimit s而崩潰(具體來說,在我的情況下,堆棧大小爲-s)。如何在適用於子級的Perl腳本中設置ulimit?

因此,我想設置一個ulimit適用於從我的主Perl內啓動的所有腳本(children),但我不知道如何實現這一點 - 任何嘗試從腳本內調用ulimit只能將其設置在立即退出的特定子shell上。

我知道,我可以在運行Perl腳本或使用/etc/security/limits.conf之前調用ulimit,但我不希望用戶知道這些 - 他們應該只知道如何運行腳本,這應該照顧所有這些對他們來說。

我每次運行一個命令時也可以運行ulimit,就像這樣ulimit -s BLA; ./cmd但我不想每次都重複這個,我覺得這裏有一個更好,更乾淨的解決方案。

另一個瘋狂的「解決方法」是製作一個名爲BLA.sh的包裝腳本,它將設置ulimit並調用BLA.pl,但這又是一個黑客,現在我有兩個腳本(我甚至可以使BLA.pl自動調用「ulimit -s BLA; ./BLA.pl --foo」,並根據它是否看到--foo或不同,採取不同的行動,但這比以前更加黑客)。

最後,顯然我可以安裝BSD ::資源,但我想避免使用外部依賴。

那麼什麼是THE如何設置Perl腳本中的ulimit並使其適用於所有的孩子?

謝謝。

+2

只需使用BSD :: Resource。或者,編譯你自己的XS模塊來做同樣的事情。不知道爲什麼你會那樣做。 – ysth 2010-02-09 02:34:58

回答

1

我結束了在前面加上ulimit -s BLA到需要它的命令。我特別不想使用BSD :: Resource,因爲它不是默認的Perl軟件包,並且在大約一半的現有開發機器上缺少。沒有用戶交互是特定的要求。

12

您已經回答了您的問題:請使用BSD::Resource

Perl核心中沒有與setrlimit連接的東西。如果你不能(或不會)使用標準方法,那麼你必須使用黑客。你已經描述的任何方法都可以工作。 (請注意,您可以創建一個子程序預先考慮ulimit -s BLA;每一個命令,然後使用該子代替system。)

+0

我不想使用外部代碼,正如我所提到的。腳本本身是潛在的全新機器的安裝程序。如果有一種方法可以不使用任何模塊,我寧願採用這種方法。必須有更好的東西... – 2010-02-09 06:58:10

+0

那麼,你可以做什麼在模塊中。這不像你被禁止看源頭。 – 2010-09-23 00:56:19

+0

@brian d foy,模塊需要XS,所以自定義模塊的安裝與CPAN版本一樣多。 – cjm 2010-09-23 02:20:13

4

您可以隨時換你的Perl在一個小的shell腳本:

#!/bin/sh -- # --*-Perl-*-- 
ulimit -n 2048 
exec /usr/bin/perl -x -S $0 ${1+"[email protected]"} 
#!/usr/bin/perl 
#line 6 

use strict; 

# etc, etc.... 

這是醜陋的,很顯然,腳本啓動時間會稍長。

+0

請注意,這會給出一個錯誤(至少在Ubuntu/debian上):'/ bin/sh:0:非法選項--' - 請參閱man perlrun以獲取正確的語法。特別是'perl'開始註釋行本身應該在一行上 – arielf 2017-06-02 21:38:16

4

下面是如何設置cpu限制而不使用BSD :: Resource(但假設perl系統頭文件存在)的示例。爲了適應其他資源,做出明顯的改變。

require 'syscall.ph'; 
require 'sys/resource.ph'; 

# set the soft cpu limit to 1 (second), and the hard limit to 10. 
$rstruct = pack "L!L!",1,10; # L! means native long unsigned int. 
syscall(&SYS_setrlimit,&RLIMIT_CPU,$rstruct); 

這個假設知道rlim_t實際上是無符號long;我不知道是否有辦法從Perl頭文件中提取這些信息。

+0

Perl在5.14.2及更早版本中提供了「sys/resource.ph」,但它不再出現在5.20.2及更高版本中...... – Onlyjob 2015-12-26 11:56:04