Как установить ulimit внутри сценария Perl, который применяется к его дочерним элементам?

StackOverflow https://stackoverflow.com/questions/2226329

  •  19-09-2019
  •  | 
  •  

Вопрос

У меня есть сценарий Perl, который выполняет различные этапы установки для настройки среды разработки для нашей компании.Он запускает различные сценарии оболочки, некоторые из которых завершаются сбоем из-за более низкого уровня, чем требуется. ulimits (в частности, размер стека -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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top