2016-10-28 1 views
1

J'ai un script bash, que je courais de la ligne de commande avec env, rediriger sa sortie vers log.txtAppel script bash de perl de manière nonbloking et obtenir un pid de ce nouveau processus d'arrière-plan

env FOO=hello BAR=world ./myscript &> log.txt 

Je veux courir quelques instances non bloquantes de myscript de perl dans arrière-plan.

Et à son tour script Perl est couru d'un autre script bash mainScript de cette façon:

#!/bin/bash -x 
perlScript.pl | tee main-log.txt 

Je sais, je peux le faire en Perl system() appel dans une boucle comme celui-ci

my $result = system("env FOO=hello BAR=world ./myscript &> log.txt &"); 

J'utilise fork et exec appels de perl comme ceci pour exécuter myscript en arrière-plan et obtenir son pid:

$run_cmd = "./myscript"; 
$run_cmd.= " &> log.txt"; 

defined(my $pid = fork) or die "$0: fork: $!\n"; 
if (!$pid) { # child code is here 

    $ENV{FOO} = 'hello'; 
    $ENV{BAR} = 'world'; 

    exec "exec $run_cmd"; 
    die "$0: failed to exec sh: $!\n"; 

} 

# parent code continues here 
print "PID of run_cmd: $pid \n"; 

Mais je trouve que quand j'utiliser la pipe | et tee à l'intérieur mainScript

| tee main-log.txt 

Je ne peux pas voir la sortie à l'écran après la création de nouvelles proceess pour myScript dans perl

Si J'appelle perlScript.pl de mainScript sans tee tout est ok.

Comment puis-je utiliser tee dans ce cas, ou peut-être il y a une autre façon de rediriger la sortie de mainScript, qu'il irait à la fois sur l'écran et certains fichiers journal?

+4

Votre instruction sur fork/exec est erronée. Fork/exec créera un tout nouveau processus en cours d'exécution indépendamment de votre script Perl. –

+0

Je pense que la meilleure solution à votre problème impliquera un changement de myscript, à savoir déplacer la redirection de sortie de la ligne de commande à l'intérieur du script.Est-ce possible dans votre situation, ou êtes-vous incapable de modifier le script? C'est un joli petit changement. – Charley

+0

@MichaelAlbers J'ai mis à jour ma hiérarchie d'appel de scripts de clarifing, qui est 'mainScript -> perlScript-> myscript'. Sans mainScript tout fonctionne parfaitement avec ** fork/exec **, mais si je cours trought hiérarchie complète perlScript est bloqué pour une raison quelconque. – Andrew

Répondre

1

Ce n'est pas testé, mais ne peut pas vous faire exactement cela?

defined(my $pid = fork) or die "$0: fork: $!\n"; 
if (!$pid) { 
    $ENV{FOO} = 'hello'; 
    $ENV{BAR} = 'world'; 
    exec 'exec ./myscript &> log.txt'; 
    die "$0: failed to exec sh: $!\n"; 
} 
# parent process here, child pid is in $pid 

Vous pouvez même faire la redirection de sortie en Perl, l'enregistrement d'un appel à la coquille:

open STDOUT, '>', 'log.txt' or die "$0: log.txt: $!\n"; 
    open STDERR, '>&', \*STDOUT or die "$0: dup(stdout): $!\n"; 
    exec './myscript'; 
    die "$0: ./myscript: $!\n"; 
0

Utilisez open:

my $pid = open(my $h, "$cmd |"); 

Ensuite, vous pouvez lire la sortie cmd à partir de la poignée h:

while (<$h>) { 
    print "$_\n"; 
}