How do I set a ulimit from inside a Perl script that applies to its children?

我是研究僧i 提交于 2019-11-30 15:21:41

问题


I have a Perl script that does various installation steps to set up a development box for our company. It runs various shell scripts, some of which crash due to lower than required ulimits (specifically, stack size -s in my case).

Therefore, I'd like to set a ulimit that would apply to all scripts (children) started from within my main Perl one, but I am not sure how to achieve that - any attempts at calling ulimit from within the script only set it on that specific child shell, which immediately exits.

I am aware that I can call ulimit before I run the Perl script or use /etc/security/limits.conf but I don't want the user to know any of this - they should only know how to run the script, which should take care of all of that for them.

I can also run ulimit every time I run a command, like this ulimit -s BLA; ./cmd but I don't want to duplicate this every time and I feel like there's a better, cleaner solution out there.

Another crazy "workaround" is to make a wrapper script called BLA.sh which would set ulimit and call BLA.pl, but again, it's a hack in my mind and now I'd have 2 scripts (I could even make BLA.pl call itself with "ulimit -s BLA; ./BLA.pl --foo" and act differently based on whether it sees --foo or not but that's even hackier than before).

Finally, apparently I could install BSD::Resource but I'd like to avoid using external dependencies.

So what is THE way to set the ulimit from within a Perl script and make it apply to all children?

Thank you.


回答1:


You've already answered your question: use BSD::Resource.

There isn't anything in the Perl core that interfaces with setrlimit. If you can't (or won't) use the standard method, then you have to use a hack. Any of the methods you've already described would work. (Note that you could create a subroutine to prepend ulimit -s BLA; to every command, and then use that sub instead of system.)




回答2:


You can always wrap your perl in a little shell script:

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

use strict;

# etc, etc....

It's ugly, and obviously, script start up time will be slightly longer.




回答3:


Here's an example of how to set the cpu limit without using BSD::Resource (but assuming the perl system headers are there). To adapt to other resources, make the obvious changes.

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);

This assumes knowledge that rlim_t is in fact unsigned long; I don't know if there's a way to extract this info from the Perl headers.




回答4:


I ended up prepending ulimit -s BLA to the commands that needed it. I specifically didn't want to go with BSD::Resource because it's not a default Perl package and was missing on about half of the existing dev machines. No user interaction was a specific requirement.



来源:https://stackoverflow.com/questions/2226329/how-do-i-set-a-ulimit-from-inside-a-perl-script-that-applies-to-its-children

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!