3 Stimmen

Kann ich Shell-Aufrufe von Perl erfassen?

Ich habe ein Perl-Skript, das andere Programme aufruft, d.h. es ruft system und/oder exec und/oder open mit einem Pipe auf und/oder verwendet den Backtick-Operator.

Kann ich dieses Skript so ausführen, dass es die Argumente für jeden der oben genannten Befehle ausgibt, damit ich sehen kann, was es aufruft?

Zum Beispiel ein Programm wie dieses das ich nicht ändern kann

#!/usr/bin/perl
sub get_arg {return "argument$_[0]";}
system "./foo", get_arg(1), get_arg(2);
print `./foo abc def`;

Möglicherweise aufgerufen wie folgt

perl --shell-trace-on ./myscript.pl

Was in diesem Fall ausgegeben wird

./foo argument1 argument2
./foo abc def

Es ist akzeptabel, die normale Ausgabe von myscript.pl zu verwerfen oder mit dieser Spur zu kombinieren.

Vielen Dank.

5voto

mob Punkte 113680

Dies wird als fortgeschrittenes Perl betrachtet, aber Sie können Unterprogramme im Namensraum CORE::GLOBAL zur Übersetzungszeit definieren und die integrierten Funktionen von Perl übernehmen. Das Aufrufen von Funktionen im Namensraum CORE wird die Original-Integrierten Funktionen aufrufen.

BEGIN {
    # muss einen BEGIN-Block verwenden, damit diese Funktionen vor der Ausführungszeit definiert sind
    *CORE::GLOBAL::system = sub {
        print STDERR "kurz davor, system @_\n";
        return CORE::system(@_);
    };
    *CORE::GLOBAL::qx = sub {
        print STDERR "kurz davor, qx/backticks @_\n";
        return CORE::qx(@_);
    };
    *CORE::GLOBAL::exec = sub { ... };
};
system("sleep 5");
print `ls`;
1;

Um dieses Feature auf ein beliebiges eigenständiges Skript anzuwenden, können Sie diesen Code in ein einfaches Modul (zum Beispiel ShellTrace.pm) einfügen und dann perl mit dem Schalter -MShellTrace aufrufen. (HT: perlman):

package ShellTrace;
BEGIN {
    *CORE::GLOBAL::system = sub { ... };
    *CORE::GLOBAL::qx = sub { ... };
    *CORE::GLOBAL::exec = sub { ... };
    *CORE::GLOBAL::open = sub { ... };
}
1;

$ perl -MShellTrace ./myscript.pl
kurz davor, system ./foo argument1 argument2 
kurz davor, qx/backticks ./foo abc def
...

1voto

Victor Bruno Punkte 1035

Nein, das Systemkommando speichert den ausgeführten Befehl nicht in speziellen Variablen.

#!/usr/bin/perl
sub get_arg {return "argument$_[0]";}
my $command = './foo ' . join(' ', get_arg(1), get_arg(2));
print "$command\n";
my $resp = `$command`; # or system($command);
print `ls *bar*`;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X