J'ai un script Perl qui effectue des tâches, dont l'une est d'appeler une commande code> system code> sur Cela peut souvent prendre un peu de temps, je voudrais donc que la ligne de commande échoue à un indicateur de progression, quelque chose comme un Je fais des creuser et jeté sur J'ai également vu des références à "gar -cvf fichier.tar ....." code> .
# code> retour à l'écran tandis que le système
code> L'appel est en cours. P>
Fourche code>. Est-ce la meilleure façon d'aller? Est-il possible de faire une fourchette de la commande code> system code>, puis créez une boucle tandis que vérifie le STAUS du
$ pid code> renvoyé par la fourchette? P>
WaiterPID code> .... Je suppose que je dois l'utiliser aussi. P>
fork system("tar ... ")
while ( forked process is still active) {
print #
sleep 1
}
6 Réponses :
J'essaierais quelque chose comme ça
open my $tar, "tar -cvf file.tar..... 2>&/dev/null |" or die "can't fork: $!"; my $i = 0; while (<$tar>) { if( i++ % 1000 == 0 ) print; } close $tar or die "tar error: $! $?";
Veuillez utiliser des lexicaux locaux pour vos poignées de fichier / processus, pas de globaux.
Mon Perl est un peu rouillé, je ne savais pas que cela est possible pour les charges de fichiers. Merci, je vais essayer la prochaine fois.
Perl a une belle construction pour cela, appelée "pipe ouvre". Vous pouvez en savoir plus à ce sujet en tapant perdoc -f ouvert code> à une invite de shell.
open(my $tar, '-|', 'tar', ...) or die "Could not run tar ... - $!";
while (<$tar>) {
print ".";
}
print "\n";
close($tar);
Bonjour Johan ... C'est exactement ce que je suis après! Merci beaucoup pour votre réponse et votre exemple. Je trouve toujours beaucoup plus facile lorsque vous voyez un code exemple. Cordialement John
La virgule n'est pas nécessaire, je l'ai retirée de l'exemple ;-)
:-) - Merci Johan. Une chose ... Cette méthode ne fonctionne-t-elle que sur des commandes qui écrivent quelque chose à STDOUT? Il semble fonctionner parfaitement lors de l'utilisation de Tar ZCVF, mais il y a une autre commande que j'utilise qui ne fait rien écho à STDOUT ..... quand j'essaie d'ouvrir un tuyau à cette commande, je ne vois pas l'impression " . " :(
@John Oui, cela ne fonctionne que si la commande écrit quelque chose. Si le processus d'enfant n'écrit rien, vous devez utiliser une construction différente, comme Fork code> /
EXEC code> / non bloque
waiterpid code> /
/
Dormez code>. @Johan Votre exemple de code serait meilleur avec un
$ | ++ code> afin que les points soient imprimés immédiatement. :)
Un exemple qui ne dépend pas du processus d'enfant qui écrit un type de sortie et imprime simplement un point environ une fois une seconde aussi longtemps que fonctionnant:
use POSIX qw(:sys_wait_h); $|++; defined(my $pid = fork) or die "Couldn't fork: $!"; if (!$pid) { # Child exec('long_running_command', @args) or die "Couldn't exec: $!"; } else { # Parent while (! waitpid($pid, WNOHANG)) { print "."; sleep 1; } print "\n"; }
Bonjour et merci pour votre aide à ce sujet. Je vais essayer cela aussi et voir quelle méthode les meilleures conversations. J'ai aimé votre caisse $ | ++ ci-dessus. Je fais un SELECT (stdout) puis $ | = 1
$|++; open(my $tar, 'tar ... |') or die "Could not run tar ... - $!"; while ($file=<$tar>) { print "$file"; } print "\n"; close($tar); This prints the filenames received from tar.
Développer sur les Hobbs fournis si vous souhaitez obtenir les données du processus enfant dans le processus parent, vous devez disposer d'un conduit externe. J'ai fini par utiliser les TEMPFS car il était simple comme un fichier, mais ne met pas de hashits io sur le disque.
** IMPORTANT **
Vous devez quitter le processus enfant, car sinon, le processus "enfant" se poursuivra le long du même script et vous obtiendrez DOUBLE Imprimer les déclarations code>. Donc, dans l'exemple ci-dessous
foreach (@stdoutoutput) code> arriverait deux fois malgré seulement d'être dans le script une fois. p>
La valeur de retour de
Fourchette code> est l'ID de processus de l'enfant, s'il s'agit du parent, ou de 0 s'il s'agit de l'enfant, ou de la FUND si la fourche a échoué. Voir Perldoc -f Fourche.