Je suis en cours d'exécution de l'extrait de code ci-dessous sur Windows. Le serveur commence à écouter en continu après la lecture du client. Je veux mettre fin à cette commande après une période de temps.
Si j'utilise alarme () a > Appel de fonction dans mais de cette manière, je n'ai pas pu prendre la sortie de ce système Quelqu'un pourrait-il me permettre de me permettre de mettre fin à la limite d'un système dans les deux sens Main.pl Code>, puis terminer le programme Perl complet (ici
Main.pl code>), donc j'ai appelé ce System commande en le plaçant dans un fichier PERL séparé
et appeler ce fichier perl (
alarm.pl code>) dans le fichier PERL d'origine à l'aide de Système commande. p>
système () code> appelé ni dans le fichier Perl d'origine ni dans l'appel d'un Perl. Fichier. P>
système () code> d'une manière ou de prendre la sortie de cette façon, j'ai utilisé ci-dessus? P>
Main .pl h3>
alarm.pl h3>
display.txt code> est toujours vide. p> p>
4 Réponses :
Il y a quelques problèmes distincts ici. P>
Premier, pour garder le Alarme de tuer votre script, vous devez gérer le Signal Alrm. Voir le Alarme Documentation. Vous ne devriez pas avoir besoin de deux scripts pour cela. P>
second, système ne capture pas la sortie. Vous avez besoin d'une des variantes de backtick ou d'un tuyau si vous voulez le faire. Il y a déjà des réponses sur Stackoverflow. P>
troisième, si alarm.pl em> met quelque chose dans display.txt em>, vous le supprimez dans Main.pl em> lorsque vous rouvrez le fichier en mode écriture. Vous avez seulement besoin de créer le fichier au même endroit. Lorsque vous vous débarrassez du script supplémentaire, vous n'aurez pas ce problème. P>
J'ai récemment eu des problèmes avec bonne chance, :) p> alarme code> et
système code>, mais commutation sur IPC :: System :: Simple corrigé. P>
Eh bien, j'ai effectivement travaillé sur ce problème cette semaine, alors j'ai été apprêtée pour cela.
Comme vous l'avez dit, j'ai essayé d'utiliser un seul fichier principal.pl et utiliser ReadPipe () au lieu de System () pour capturer la sortie dans un fichier TXT. My @ Sortie_1 = Readpipe ("iperf -u -s -p 5001"); Ouvrir le fichier, "> display.txt" ou die $!; Fichier d'impression @ Sortie_1; Fermer le fichier; Après l'exécution de la commande Readpipe, il se bloque à ci-dessous et ici I [3] 0.0-10,7 sec 301 kbits 231 kbits / s veut sortir de cette commande ReadPpePpe et prendre TheOutput dans un fichier TXT, mais je ne sais pas comment gérer La fonction d'alarme ici Pourriez-vous s'il vous plaît élaborer beaucoup de WRT mon extrait de code ci-dessus.
Qu'est-ce que je pensais? Vous n'avez pas besoin d'un processus de fond pour cette tâche. Il vous suffit de suivre l'exemple dans le perdoc -f alarme code> a > Fonction et enveloppez votre code sensible au temps dans un bloc
EVAL code>.
$command = "adb shell cd /data/app; ./iperf -u -s -p 5001";
if (($pid = fork()) == 0) {
# child process
$SIG{ALRM} = sub { die "Timeout\n" }; # handling SIGALRM in child is optional
alarm 30;
my $c = system($command);
alarm 0;
exit $c >> 8; # if you want to capture the exit status
}
# parent
waitpid $pid, 0;
J'exécute ce programme sous Windows à l'aide de Perl Interprète, vous serez-vous sûr que cela sera OK sous Windows, BTW où la sortie est-elle capturée de la commande système? rocheux..
@rockyurock - Mise à jour ma réponse. Utilisez qx code> ou
réadappe code> ou backticks si vous souhaitez capturer la sortie.
@MOB - Y a-t-il une manière qui peut être modifiée de sorte que, au lieu de se terminer après le délai d'attente, il finira plutôt que lorsque l'utilisateur appuie sur un bouton sur le clavier ou les types "Quitter" par exemple? Merci pour votre aide
Peut utiliser "Timeout -N" pour envelopper vos commandes si cela est déjà commun sur votre système. P>
Je rencontre un problème similaire qui nécessite:
Après beaucoup de lecture sur Perl IPC et Manuel Fork & Exec, je suis sorti de cette solution. Il est implémenté comme un sous-programme simulé de «backtk». P>
use Error qw(:try); $SIG{ALRM} = sub { my $sig_name = shift; die "Timeout by signal [$sig_name]\n"; }; # example my $command = "vmstat 1 1000000"; my $output = backtick( command => $command, timeout => 60, verbose => 0 ); sub backtick { my %arg = ( command => undef, timeout => 900, verbose => 1, @_, ); my @output; defined( my $pid = open( KID, "-|" ) ) or die "Can't fork: $!\n"; if ($pid) { # parent # print "parent: child pid [$pid]\n" if $arg{verbose}; try { alarm( $arg{timeout} ); while (<KID>) { chomp; push @output, $_; } alarm(0); } catch Error with { my $err = shift; print $err->{-text} . "\n"; print "Killing child process [$pid] ...\n" if $arg{verbose}; kill -9, $pid; print "Killed\n" if $arg{verbose}; alarm(0); } finally {}; } else { # child # set the child process to be a group leader, so that # kill -9 will kill it and all its descendents setpgrp( 0, 0 ); # print "child: pid [$pid]\n" if $arg{verbose}; exec $arg{command}; exit; } wantarray ? @output : join( "\n", @output ); }