如何在适用于子级的Perl脚本中设置ulimit?

我有一个Perl脚本,执行各种安装步骤来为我们公司设置一个开发框。 它运行各种shell脚本,其中一些由于低于所需的ulimit (特别是堆栈大小 – 在我的情况下)而崩溃。

因此,我想设置一个适用于从我的主Perl中启动的所有脚本( children )的ulimit ,但我不知道如何实现这一点 – 任何从脚本内调用ulimit的尝试只设置它该特定的子shell,立即退出。

我知道我可以在运行Perl脚本之前调用ulimit或者使用/etc/security/limits.conf但是我不希望用户知道这些 – 他们只应该知道如何运行脚本,它应该为他们照顾这一切。

我也可以在每次运行命令时运行ulimit ,像这样ulimit -s BLA; ./cmd ulimit -s BLA; ./cmd但我不想每次重复这个,我觉得有一个更好,更干净的解决scheme。

另一个疯狂的“解决方法”是制作一个名为BLA.sh的包装脚本,它将设置ulimit并调用BLA.pl,但是在我看来,这是一个破解,现在我有两个脚本(我甚至可以使BLA.pl用“ulimit -s BLA; ./BLA.pl-foo”来调用自己,根据它是否看到–foo而不同,但是这比以前更加黑客)。

最后,显然我可以安装BSD ::资源,但我想避免使用外部依赖。

那么从Perl脚本中设置ulimit的方法是什么,并使其适用于所有的孩子?

谢谢。

你已经回答了你的问题:使用BSD ::资源 。

Perl内核中没有任何与setrlimit 。 如果你不能(或不会)使用标准的方法,那么你必须使用黑客。 你已经描述的任何方法都可以工作。 (请注意,您可以创建一个子程序来为每个命令添加ulimit -s BLA;然后使用该子代替system 。)

你总是可以将你的perl包装在一个shell脚本中:

 #!/bin/sh -- # --*-Perl-*-- ulimit -n 2048 exec /usr/bin/perl -x -S $0 ${1+"$@"} #!/usr/bin/perl #line 6 use strict; # etc, etc.... 

这是丑陋的,显然,脚本启动时间会稍长。

这里是一个如何设置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标题中提取这些信息。

我结束了ulimit -s BLA到需要它的命令。 我特别不想使用BSD :: Resource,因为它不是默认的Perl软件包,在大约一半的现有开发机器上缺少。 没有用户交互是一个特定的要求。