Wie kann ich den Standard -Ausgabedateihandle für einen Systemaufruf in Perl ändern?

StackOverflow https://stackoverflow.com/questions/990913

  •  13-09-2019
  •  | 
  •  

Frage

Ich versuche die STDOut der Systemfunktion mithilfe von SELECT zu ändern. Aber es scheint nicht zu funktionieren. Die Systemausgabe wird auf der Konsole angezeigt, anstatt in die Datei umgeleitet zu werden.

use strict;
use warnings;

chdir "C:\\Documents and Settings\\" or die "cannot open the dir\n";
open FH, ">out.txt" or die "cannot open out.txt\n";
select FH or die " cannot change the stdout\n";
system "dir /a" ; 

Obwohl ich das tun kann system "dir /a > out.txt", Ich möchte wissen, warum der obige Code nicht funktioniert.

War es hilfreich?

Lösung

Das select Funktion ändert den Standarddateihandle für die Ausgabe. Es ändert sich nicht an STDOut, wodurch auf alles hinweist, auf das es hinweist, unabhängig davon, ob es sich um den Standarddateihandle für die Ausgabe handelt. Wenn Sie Stdout ändern möchten, müssen Sie so etwas wie Ylebre oder Jons Antwort tun.

Wenn Sie einen untergeordneten Prozess starten, erhält es die gleiche Standardausgabe wie der Elternteil. Es ist es egal, was der Standarddateihandle des übergeordneten übergeordnet ist.

Andere Tipps

Das Problem mit Ihrem Code ist das system Der Befehl erfasst die Ausgabe nicht für Sie. Sie können verwenden qx//:

use strict;
use warnings;

open my $fh, ">", "output.txt" or die $!;
my $oldfh= select $fh;
print qx/ls -a/;
select $oldfh;
close $fh or warn $!;

Es gibt andere Optionen, um eine externe Anwendung auszuführen und Lesen der Ausgabe zu erhalten, wie die IPC::Open2 und IPC::Open3 Module. Sie sind standardmäßig in Perl enthalten.

Randnotiz: Verwenden Sie keine Globs für Dateigriffe: Sie sind Globale und Globale sind böse. Verwenden Sie stattdessen lexikalische Variablen (FH vs. $fh). Außerdem sollten Sie die drei Argumente verwenden open Anstelle von zwei Parametern, da erstere sicherer ist als der letztere.

Vielleicht Dies hilft

Ich bin mir nicht sicher, wonach Sie in diesem Fall suchen. Um Stdout in eine Datei umzuleiten, können Sie Folgendes ausführen:

use strict;
use warnings;
use IO::Handle;
open FH, "> out.txt";
STDOUT->fdopen( \*FH, 'w' ) or die $!;
print "Hello world!\n";
system "dir /a";

Hoffe das hilft!

Ich habe die Dateideskriptoren auf der Ebene des Systems (nicht Perl) zugewiesen:

    sub reopen($$$) {
        open $_[0], $_[1]. '&='. fileno($_[2]) or die "failed to reopen: $!";
    }

    reopen *STDOUT,  '>', $new_stdout_handle;

Jetzt ist alles, was Sie Fork haben, $ new_stdout_handle ist Standardausgabe.

Ich habe ein vollständiges Beispiel an GIST eingefügt: http://gist.github.com/129407

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