2010-02-09 12 views
7

Ho uno script Perl che esegue varie fasi di installazione per configurare una casella di sviluppo per la nostra azienda. Esegue vari script di shell, alcuni dei quali bloccati a causa di un numero inferiore a quello richiesto ulimit s (in particolare, stack size -s nel mio caso).Come impostare un ulimit all'interno di uno script Perl che si applica ai suoi figli?

Pertanto, vorrei impostare uno ulimit applicabile a tutti gli script (children) avviato dal mio Perl principale, ma non sono sicuro di come ottenerlo: qualsiasi tentativo di chiamare ulimit dallo script impostalo solo su quella specifica shell figlio, che esce immediatamente.

Sono consapevole che posso chiamare ulimit prima ho eseguito lo script Perl o utilizzare /etc/security/limits.conf, ma non voglio che l'utente sappia niente di tutto questo - dovrebbero solo sapere come eseguire lo script, che dovrebbe prendersi cura di tutto questo per loro.

Posso anche eseguire ulimit ogni volta che eseguo un comando, come questo ulimit -s BLA; ./cmd ma non voglio duplicarlo ogni volta e mi sento come se ci fosse una soluzione migliore, più pulita là fuori.

Un'altra pazzesca "soluzione" è creare uno script wrapper chiamato BLA.sh che stabilisca ulimit e chiami BLA.pl, ma ancora una volta, è un hack nella mia mente e ora avrei 2 script (potrei anche fai in modo che BLA.pl si chiami da solo con "ulimit -s BLA; ./BLA.pl --foo" e agisca diversamente a seconda che veda --foo o meno ma che sia anche più hacker di prima).

Infine, apparentemente potrei installare BSD :: Risorsa ma vorrei evitare l'uso di dipendenze esterne.

Quindi cos'è IL modo per impostare ulimit all'interno di uno script Perl e farlo applicare a tutti i bambini?

Grazie.

+2

basta usare BSD :: Risorsa. in alternativa, compila il tuo modulo XS per fare lo stesso. Non so perché lo faresti, comunque. – ysth

risposta

1

ho finito per anteporre ulimit -s BLA ai comandi che ne avevano bisogno. In particolare non volevo andare con BSD :: Resource perché non è un pacchetto Perl di default e mancava su circa la metà delle macchine di sviluppo esistenti. Nessuna interazione dell'utente era un requisito specifico.

12

Hai già risposto alla tua domanda: usa BSD::Resource.

Non c'è nulla nel core Perl che si interfaccia con setrlimit. Se non puoi (o non vuoi) usare il metodo standard, allora devi usare un trucco. Qualunque metodo tu abbia già descritto funzionerebbe. (Si noti che è possibile creare una subroutine per anteporre ulimit -s BLA; per ogni comando, e quindi utilizzare tale sub invece di system.)

+0

Non voglio usare deps esterni, come ho detto. Lo script stesso è un programma di installazione per una macchina potenzialmente nuova di zecca. Se c'è un modo per farlo senza alcun modulo, preferirei optare per questo approccio. Deve esserci qualcosa di meglio ... –

+0

Beh, potresti semplicemente fare quello che c'è nel modulo. Non è che ti sia proibito guardare la fonte. –

+0

@brian d foy, il modulo richiede XS, quindi un modulo personalizzato sarebbe tanto lavoro da installare quanto la versione CPAN. – cjm

4

È sempre possibile avvolgere la perl in uno script piccolo guscio:

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

use strict; 

# etc, etc.... 

E 'brutto, e, ovviamente, script di avvio tempo sarà leggermente più lungo.

+0

Si noti che questo dà un errore (almeno su Ubuntu/debian): '/ bin/sh: 0: Opzione non valida -' - Si veda 'man perlrun' per la sintassi corretta. In particolare la linea di commento di inizio 'perl' dovrebbe essere su una riga di per sé – arielf

4

Ecco un esempio di come impostare il limite della CPU senza utilizzare BSD :: Resource (ma assumendo che le intestazioni del sistema perl siano presenti). Per adattarsi ad altre risorse, apportare le modifiche ovvie.

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

Questo presuppone che rlim_t sia in realtà non firmato a lungo; Non so se c'è un modo per estrarre queste informazioni dagli header Perl.

+0

Perl fornito" sys/resource.ph "in 5.14.2 e versioni precedenti ma non è più presente in 5.20.2 e versioni successive ... – Onlyjob

Problemi correlati