Frage

In Perl auszuführen, können Sie die system-Befehle mit Hilfe von system() oder ` (backticks).Sie können sogar erfassen Sie die Ausgabe des Befehls in eine variable.Jedoch, dieser blendet das Programm die Ausführung im hintergrund, so dass die person, die Ihr Skript kann es nicht sehen.

Dies ist normalerweise nützlich, aber manchmal will ich sehen, was Los ist hinter den kulissen.Wie machen Sie es, damit die Befehle ausgeführt werden gedruckt, um das terminal, und jene Programme, die die Ausgabe gedruckt, um das terminal?Dies wäre der .bat entspricht "@echo on".

War es hilfreich?

Lösung

So wie ich das verstehe, system() druckt das Ergebnis des Befehls, aber nicht zuordnen.ZB.

[daniel@tux /]$ perl -e '$ls = system("ls"); print "Result: $ls\n"'
bin   dev  home  lost+found  misc  net  proc  sbin     srv  System  tools  var
boot  etc  lib   media       mnt   opt  root  selinux  sys  tmp     usr
Result: 0

Backticks werden erfassen Sie die Ausgabe des Befehls und nicht drucken:

[daniel@tux /]$ perl -e '$ls = `ls`; print "Result: $ls\n"'
Result: bin
boot
dev
etc
home
lib

etc...

Update: Wenn Sie möchten, drucken Sie die Namen der Befehl system()'d wie gut, denke ich Rudd's-Ansatz gut ist.Hier wiederholt für die Konsolidierung:

sub execute {
    my $cmd = shift;
    print "$cmd\n";
    system($cmd);
}

my $cmd = $ARGV[0];
execute($cmd);

Andere Tipps

Ich kenne keine Standard-Weg, dies zu tun, aber definieren Sie eine subroutine, um es für Sie tun:

sub execute {
    my $cmd = shift;
    print "$cmd\n";
    system($cmd);
}

my $cmd = $ARGV[0];
execute($cmd);

Und dann sehen Sie es in Aktion:

pbook:~/foo rudd$ perl foo.pl ls
ls
file1   file2   foo.pl

Verwenden Sie open statt.Dann erfassen Sie die Ausgabe des Befehls.

open(LS,"|ls");
print LS;

Hier ist eine Aktualisierung ausgeführt wird, drucken Sie die Ergebnisse und geben Sie Sie zurück:

sub execute {
  my $cmd = shift;
  print "$cmd\n";
  my $ret = `$cmd`;
  print $ret;
  return $ret;
}

Hmm, interessant, wie verschiedene Menschen Antwort auf diese verschiedenen Möglichkeiten.Es sieht für mich so aus mk und Daniel Fone interpretiert es so wollen, um zu sehen/Bearbeiten der stdout des Befehls (weder Ihrer Lösungen erfassen stderr fwiw).Ich denke, Rudd näher kam.Ein twist, den man machen könnte auf rudds Antwort auf overwite das eingebaute system () - Befehl mit Ihrer eigenen version, so dass Sie nicht haben, zu umschreiben, bestehenden code zu nutzen sein execute () - Befehl.

mit seinem execute () - sub von rudds post, Sie könnte so etwas wie dies oben in Ihrem code:

if ($DEBUG) {
   *{"CORE::GLOBAL::system"} = \&{"main::execute"};
}

Ich denke, dass es funktionieren wird, aber ich muss zugeben, das ist voodoo und es ist schon eine Weile her, seit ich diesen code schrieb.Hier ist der code, den ich schrieb vor Jahren zum abfangen von Systemaufrufen, die auf einem lokalen (calling namespace) oder globaler Ebene bei-Modul laden:

  # importing into either the calling or global namespace _must_ be
  # done from import().  Doing it elsewhere will not have desired results.
  delete($opts{handle_system});
  if ($do_system) {
    if ($do_system eq 'local') {
      *{"$callpkg\::system"} = \&{"$_package\::system"};
    } else {
      *{"CORE::GLOBAL::system"} = \&{"$_package\::system"};
    }
  }

Eine andere Technik zu kombinieren mit den anderen in der erwähnten Antworten, ist die Verwendung der tee Befehl.Zum Beispiel:

open(F, "ls | tee /dev/tty |");
while (<F>) {
    print length($_), "\n";
}
close(F);

Dies wird sowohl drucken Sie die Dateien in das aktuelle Verzeichnis (als Folge von tee /dev/tty) und auch drucken Sie die Länge jedes mit dem Namen Lesen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top