Как установить ulimit внутри сценария Perl, который применяется к его дочерним элементам?
Вопрос
У меня есть сценарий Perl, который выполняет различные этапы установки для настройки среды разработки для нашей компании.Он запускает различные сценарии оболочки, некоторые из которых завершаются сбоем из-за более низкого уровня, чем требуется. ulimit
s (в частности, размер стека -s
в моем случае).
Поэтому я хотел бы установить ulimit
это применимо ко всем сценариям (children
) начался из моего основного Perl, но я не уверен, как этого добиться - любые попытки вызвать ulimit из скрипта устанавливают его только в этой конкретной дочерней оболочке, которая немедленно завершает работу.
Я знаю, что могу позвонить ulimit
прежде чем я запущу сценарий Perl или использую /etc/security/limits.conf
но я не хочу, чтобы пользователь знал что-либо из этого - он должен знать только, как запустить скрипт, который должен позаботиться обо всем этом за него.
я тоже могу бежать ulimit
каждый раз, когда я запускаю команду, вот так ulimit -s BLA; ./cmd
но я не хочу повторять это каждый раз и чувствую, что есть лучшее и более чистое решение.
Еще один сумасшедший «обходной путь» — создать сценарий-оболочку под названием BLA.sh, который бы устанавливал ulimit и вызывал BLA.pl, но, опять же, на мой взгляд, это хак, и теперь у меня было бы 2 сценария (я мог бы даже сделать BLA.pl вызвать себя с помощью «ulimit -s BLA;./BLA.pl --foo" и действовать по-разному в зависимости от того, видит он --foo или нет, но это еще сложнее, чем раньше).
Наконец, очевидно, я мог бы установить BSD::Resource, но мне хотелось бы избежать использования внешних зависимостей.
Так что же такое ТО способ установить ulimit из сценария Perl и применить его ко всем дочерним элементам?
Спасибо.
Решение 4
в итоге я добавил ulimit -s BLA
командам, которые в этом нуждались.Я специально не хотел использовать BSD::Resource, поскольку он не является пакетом Perl по умолчанию и отсутствовал примерно на половине существующих машин разработки.Никакого взаимодействия с пользователем не было особым требованием.
Другие советы
Вы уже ответили на свой вопрос:использовать BSD::Ресурс.
В ядре Perl нет ничего, что могло бы взаимодействовать с setrlimit
.Если вы не можете (или не хотите) использовать стандартный метод, вам придется использовать хак.Любой из методов, которые вы уже описали, подойдет.(Обратите внимание, что вы можете создать подпрограмму для добавления ulimit -s BLA;
к каждой команде, а затем используйте этот подпрограмму вместо system
.)
Вы всегда можете обернуть Perl в небольшой скрипт оболочки:
#!/bin/sh -- # --*-Perl-*--
ulimit -n 2048
exec /usr/bin/perl -x -S $0 ${1+"$@"}
#!/usr/bin/perl
#line 6
use strict;
# etc, etc....
Это некрасиво, и, очевидно, время запуска скрипта будет немного дольше.
Вот пример того, как установить ограничение процессора без использования 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 на самом деле имеет длину без знака;Я не знаю, есть ли способ извлечь эту информацию из заголовков Perl.