我有一个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软件包,在大约一半的现有开发机器上缺少。 没有用户交互是一个特定的要求。