[gelöst] Perl: Maskierung beim Aufruf von system()
[gelöst] Perl: Maskierung beim Aufruf von system()
Hallo zusammen!
Ich habe ein Maskierungsproblem bei der Funktion system() in Perl:
Ein einfaches Shell-Kommando zu übergeben wie zb. system("cat xxx | grep yyy") ist ja trivial,
aber wie gehe ich damit um, wenn ich zum Beispiel:
system("ps -ef | awk '$1=="user" && $3==1'")
aufrufen will? Das klappt wegen des awk-Konstrukts nicht.
(Das es ein Anachronismus ist awk aus Perl heraus aufzurufen, weiß ich selber Es geht um eine Quick´n´Dirty-Lösung)
Wie muss ich generell beim Aufruf von system() maskieren um ein beliebiges Shell-Kommando vollständig zu "schützen"?
Vielen Dank im voraus & Gruß aus Braunschweig
Ich habe ein Maskierungsproblem bei der Funktion system() in Perl:
Ein einfaches Shell-Kommando zu übergeben wie zb. system("cat xxx | grep yyy") ist ja trivial,
aber wie gehe ich damit um, wenn ich zum Beispiel:
system("ps -ef | awk '$1=="user" && $3==1'")
aufrufen will? Das klappt wegen des awk-Konstrukts nicht.
(Das es ein Anachronismus ist awk aus Perl heraus aufzurufen, weiß ich selber Es geht um eine Quick´n´Dirty-Lösung)
Wie muss ich generell beim Aufruf von system() maskieren um ein beliebiges Shell-Kommando vollständig zu "schützen"?
Vielen Dank im voraus & Gruß aus Braunschweig
Zuletzt geändert von zongo am 17.03.2010 11:17:04, insgesamt 1-mal geändert.
Re: Perl: Maskierung beim Aufruf von system()
Probier mal das:
Code: Alles auswählen
system("ps -ef | awk '\$1==\"user\" && \$3==1'")
Re: Perl: Maskierung beim Aufruf von system()
der ps Aufruf produziert ne hübsche Fehlermeldung beim Escapen.
system() wird mit "" aufgerufen und der ps/awk Aufruf ist auch ok.
Weil aber mehrfach doppelte "" drin sind funktioniert das nicht. Eine Idee hab ich aber im Moment auch nicht.
system() wird mit "" aufgerufen und der ps/awk Aufruf ist auch ok.
Weil aber mehrfach doppelte "" drin sind funktioniert das nicht. Eine Idee hab ich aber im Moment auch nicht.
Re: Perl: Maskierung beim Aufruf von system()
Ach ja, die gute Allgemeingültigkeit. Das Problem fängt schon bei den $-Zeichen an, denn so ohne Weiteres ist nicht klar ob die im Perl- oder im awk-Kontext stehen.
Wie kommen denn die Shell-Kommandos in den Perl-Kontext? Solche Spezialfälle wie Anführungs- und Dollarzeichen musst du schon vorher abfangen und dann ggf. über Pattern-Matching ersetzen.
Zum Beispiel ginge das:
Die Frage wäre jetzt, ob es praktikabel ist problematische Zeichen durch entsprechende Sequenzen zu ersetzen bevor sie in den Perl-Kontext kommen. Womit wir wieder beim beliebten Thema "Parser" wären.
Wie kommen denn die Shell-Kommandos in den Perl-Kontext? Solche Spezialfälle wie Anführungs- und Dollarzeichen musst du schon vorher abfangen und dann ggf. über Pattern-Matching ersetzen.
Zum Beispiel ginge das:
Code: Alles auswählen
$_ = "ps -ef | awk '#DL#1==#QT#user#QT# && #DL#3==1'";
s/#DL#/\$/g;
s/#QT#/"/g;
system($_);
Re: Perl: Maskierung beim Aufruf von system()
folgender Workaround sollte auch funktionieren. Der behebt die Probleme mit den doppelten Quotes...
Code: Alles auswählen
system("ps -ef |grep ^USER |awk '\$3==1'");
Re: Perl: Maskierung beim Aufruf von system()
wenn du an "system" eine Zeichenkette mit "..." übergibst, müssen die " und $-Zeichen maskiert werden ( außer $ steht für eine Perl-Variable):zongo hat geschrieben: Wie muss ich generell beim Aufruf von system() maskieren um ein beliebiges Shell-Kommando vollständig zu "schützen"?
Code: Alles auswählen
gms1 ~ # cat x.pl
#!/usr/bin/perl
system("ps -ef | awk '\$1==\"gms\" && \$3==1'");
gms1 ~ # ./x.pl
gms 7927 1 0 Mar07 ? 00:00:01 ssh-agent -s
...
gms1 ~ #
Code: Alles auswählen
gms1 ~ # cat x.pl
#!/usr/bin/perl
system('ps -ef | awk \'$1=="gms" && $3==1\'');
gms1 ~ #
gms1 ~ # ./x.pl
gms 7927 1 0 Mar07 ? 00:00:01 ssh-agent -s
...
gms1 ~ #
z.B system('ps -ef | awk \'$1=="'.$user.'" && $3==1\'');
Gruß
gms
Re: Perl: Maskierung beim Aufruf von system()
jetzt ist mir noch eine ( einfachere ) Variante eingefallen ( hier müssen nur die $ von Nicht-Perl-Variablen maskiert werden):
zur Sicherheit noch erwähnt: die Zeichen @ und % sind natürlich unter Perl gleich zu behandeln, wie das $-Zeichen
Code: Alles auswählen
gms1 ~ # cat x.pl
#!/usr/bin/perl
system <<EOF;
ps -ef | awk '\$1=="gms" && \$3==1'
EOF
gms1 ~ # ./x.pl
gms 7927 1 0 Mar07 ? 00:00:01 ssh-agent -s
...
Re: Perl: Maskierung beim Aufruf von system()
Man könnte bei ps noch -u verwenden um sich das grep bzw. den zweiten Vergleich in awk zu sparen:
Zudem hat man in Perl doch alternative Arten zu quoten, was hier sehr praktisch ist:
Code: Alles auswählen
system("ps -fu USER | awk '\$3==1'");
Code: Alles auswählen
system(q/ps -fu USER | awk '$3==1'/);
Use ed once in a while!
Re: Perl: Maskierung beim Aufruf von system()
in Zeile wieviel welcher Doku stand das denn? Genau das wollte er wohl ursprünglich wissen.Meillo hat geschrieben:Zudem hat man in Perl doch alternative Arten zu quoten, was hier sehr praktisch ist:Code: Alles auswählen
system(q/ps -fu USER | awk '$3==1'/);
Dann funktioniert auch sein original mit den neuen "Quotes":
Code: Alles auswählen
system(q/ps -ef | awk '$1=="user" && $3==1'/)
Re: Perl: Maskierung beim Aufruf von system()
in perlop http://perldoc.perl.org/perlop.html#Quo ... -Operatorsub13 hat geschrieben:[
in Zeile wieviel welcher Doku stand das denn? Genau das wollte er wohl ursprünglich wissen.
das soll jetzt natürlich keine Kritik an dieser Lösung sein, aber meistens hat man dann doch auch Perl-Variablen in dem String ( z.B für 'user' ) und dann wird diese Methode am unübersichtlichsten ( finde ich zumindest )ub13 hat geschrieben:[Code: Alles auswählen
system(q/ps -ef | awk '$1=="user" && $3==1'/)
Gruß
gms
Re: Perl: Maskierung beim Aufruf von system()
Im Camel-Book natürlich.ub13 hat geschrieben: in Zeile wieviel welcher Doku stand das denn? Genau das wollte er wohl ursprünglich wissen.
Das stimmt.gms hat geschrieben:das soll jetzt natürlich keine Kritik an dieser Lösung sein, aber meistens hat man dann doch auch Perl-Variablen in dem String ( z.B für 'user' ) und dann wird diese Methode am unübersichtlichsten ( finde ich zumindest )ub13 hat geschrieben:Code: Alles auswählen
system(q/ps -ef | awk '$1=="user" && $3==1'/)
Wenn Variablen enthalten sind, müssen die Dollarzeichen zwangsläufig escaped werden. Wenn man aber qq// (entspricht Double-Quotes) verwendet, dann muss man die Double-Quotes im Text nicht auch noch escapen.
Use ed once in a while!
Re: Perl: Maskierung beim Aufruf von system()
Daran lags also - ich habe gar kein Camel-Book.Meillo hat geschrieben:Im Camel-Book natürlich.
gms hat ja eine Quelle genannt. Google hätte mich (wenn ich dann nachgedacht hätte) auch schnell hingeführt.
Re: Perl: Maskierung beim Aufruf von system()
das Camel-Book wärs gewesen, ich habe aber auch kein Camel-Book , blöd , so konnte ich nur mit diesem schnöden Link zu "perlop" dienen ...ub13 hat geschrieben: Daran lags also - ich habe gar kein Camel-Book.
gms hat ja eine Quelle genannt.
Gruß
gms
Re: [gelöst] Perl: Maskierung beim Aufruf von system()
Und wieder etwas dazu gelernt ...
Muchas gracias muchachos!
Muchas gracias muchachos!