Perl a spuštění příkazů na pozadí

Rishare

Perl a spuštění příkazů na pozadí
« kdy: 19. 07. 2010, 11:56:54 »
Ahoj,

nevite nekdo prosim, jak spustit v perlu prikaz (napr.: sleep 300 && rm /tmp/test ) na pozadi?

Mam tu typicky priklad, kdy mam ve skriptu tuto radku:
system("nohup sleep 60 &");
A presto mi perl na teto radce celou minutu visi, nez jde dal.

Perl 4.0, Patch level 36, OS AIX 5.3.7.0
« Poslední změna: 19. 07. 2010, 15:58:42 od Petr Krčmář »


XSimi

Re: Perl - spusteni prikazu na pozadi
« Odpověď #1 kdy: 19. 07. 2010, 12:08:24 »
neznam perl, ale fork urcite zabere

Lubomir Rintel

Re: Perl - spusteni prikazu na pozadi
« Odpověď #2 kdy: 19. 07. 2010, 13:48:25 »
No ono si to dosti chujovo popisal co chces aby to robilo.

Pokial chces odlozit vykonanie prikazu (trebars toho unlinku), tak sa s nejakym subprocesom neser:

Kód: [Vybrat]
$SIG{ALRM} = sub { unlink '/tmp/test };
alarm 300;

Samozrejme pripad, ze tvoj program skonci skor nez alarm triggerne by si musel osetrit separatne (END blokom napriklad).

Inak tak ako vravel Rishare:

Kód: [Vybrat]
unless (fork) {
    sleep 300;
    exit unlink '/tmp/konskykokot';
}
....
wait

stilett

Re: Perl - spusteni prikazu na pozadi
« Odpověď #3 kdy: 19. 07. 2010, 13:54:54 »
Ono bohužel záleží na systému. Ten příklad, který uvádíte, mi na Linuxu funguje korektně (i bez nohup). Na AIX to vyzkoušené nemám. Zkuste modul Proc::Background, který se to snaží zobecnit. V každém případě by to měl jistit příkaz fork (v krajním případě, že by to pořád nefungovalo, ještě následovaný příkazem setsid). Jeho použití je tu uvedeno.
Je pak taky otázka, zda chcete na ukončení procesu někdy čekat (až váš skript vykoná, co potřebuje), to pak je system s příkazem s & na konci nedostatečný a ten fork se bude hodit.

Rishare

Re: Perl a spuštění příkazů na pozadí
« Odpověď #4 kdy: 20. 07. 2010, 11:44:45 »
Dekuji za ruzne rady, ale moc mi nepomohly.

Zadne dalsi moduly pouzivat nemohu (pak by to bylo celkem snadne a problem bych resil uplne jinak). Popisi tedy ten problem celkove:

Perlovy skript mi generuje html stranku (prosim nediskutujme proc perl, toto zkratka neovlivnim). Perl vygeneruje soubor, ktery si mohou uzivatele nasledujicich 5 minut stahovat a po techto 5ti minutach potrebuji, aby se smazal.

Domnival jsem se, ze nejsnazsi reseni bude spustit shellovy command na pozadi, ktery jej proste po dane dobe smaze, jenze at jsem zkousel co jsem zkousel, perlovy skript tvrdohlave cekal na ukonceni tohoto shelloveho prikazu, nez pokracoval ve vygenerovani dalsi html stranky (coz prave nemohu).

Zkratka nejvic nerozumim tomu, proc mi na AIXu Perl na prikazu
system("nohup sleep 60 &");
visi a ceka na dokonceni tohoto shelloveho prikazu, ackoliv by se IMHO mel od nej "odpoutat" a pokracovat dal. To je pro mne nejvetsi zahada. Zvladne mi to nekdo vysvetlit?



Rishare

Re: Perl a spuštění příkazů na pozadí
« Odpověď #5 kdy: 20. 07. 2010, 11:56:02 »
Jeste jsem zapomel dodat, ze tato konstrukce, kterou jsem zkousel, ma naprosto stejny vysledek (vygenerovani html ceka na dokonceni shelloveho skriptu).

Kód: [Vybrat]
defined (my $kid = fork) or die "Cannot fork: $!\n";
if ($kid) {
}
else {
setsid or die "Can't start a new session: $!";
system("nohup sleep 30 && rm /tmp/testik & 2>&1 >/tmp/out");
}

stilett

Re: Perl a spuštění příkazů na pozadí
« Odpověď #6 kdy: 20. 07. 2010, 15:17:37 »
Omg, to jste trochu překombinoval. Když už, tak bych to napsal jako:
defined (my $kid = fork) or die "Cannot fork: $!\n";
if (!$kid) {
  setsid or die "Cant start a new session: $!";
  sleep 30;
  unlink "/tmp/testik";
}


Zkuste před voláním sleep odpojit vstupy a výstupy:
open STDIN, "</dev/null";
open STDOUT, ">/dev/null";
open STDERR, '>/dev/null';


případně před odpojením ještě zavřít STDOUT.

Ale popisovaný problém lze jistě řešit jinak:
1. Pokud netrváte na těch 5 minutách přesně, můžete použít příkaz at:
system("echo 'rm /tmp/testik' | at now + 5 minute");

2. Když vám tu stránku generuje Perl, tak co ho použít jako CGI, které stránku vydá jen po dobu 5 minut?

3. Co vám brání používat moduly? Jednodušší moduly (mezi které Proc::Background patří) si můžete stáhnout (např. ze stránky http://search.cpan.org/dist/Proc-Background/lib/Proc/Background.pm), nakopírovat do libovolného adresáře a pak pomocí
use lib '/adresar/kam/jsem/ho/nakopiroval';
use Proc::Background;

zajistit, že ho skript najde.

Rishare

Re: Perl a spuštění příkazů na pozadí
« Odpověď #7 kdy: 20. 07. 2010, 16:49:50 »
Stilett: Dekuji, vyresil jsem to za pomoci prikazu at. Jednoduche a efektivni - az se stydim, ze me to nenapadlo samotneho. Vec modulu bohuzel neovlivnim, jsem pouhy zamestnanec :-)

Jeste jednou dekuji, ted se mlatim do hlavy.