system mit Shell-Metazeichen in Kommandozeilenargumenten unter Win32

04/04/2010 - 22:03 von Rolf Krahl | Report spam
Ich möchte ein externes Programm mit system aufrufen und dabei
Kommandozeilenargumente übergeben, die '&' enthalten. Testbeispiel:

Aufgerufenes Skript foo.pl:
#! /usr/bin/perl

use strict;
use warnings;

print join(':', @ARGV), "";


Aufrufendes Skript foocall.pl:
#! /usr/bin/perl

use strict;
use warnings;

my $arg = 'a&c';

system("./foo.pl", "arg=$arg", "d") == 0
or die;


Unter Linux funktioniert das auch genau so, wie man es sich denkt:

$ ./foocall.pl
arg=a&c:d


Unter Win32 wird jedoch offensichtlich das '&' im
Kommandozeilenargument als Shell-Metazeichen interpretiert, obwohl
system laut Doku dies ja gerade nicht tun soll, wenn es mit mehr als
einem Argument aufgerufen wird. Das aufgerufene Skript sieht nur das
Argument "arg=a" und zudem erhalte ich eine Fehlermeldung, daß "c"
nicht als "internal or external command" erkannt wird.

Ich muß dazu sagen, daß ich kein Windows habe und es deshalb nicht
selbst testen kann. Den beschriebenen Fehler rekonstruiere ich so aus
den Testberichten von CPAN Testern für ein Modul von mir[1]. Die oben
beschriebene Situation ist auch nur das auf das wesentliche reduzierte
Testbeispiel.

Daher nun meine Fragen:

1. Kann jemand unter Win32 (nicht Cygwin, da scheint es zu gehen) das
beschriebene Verhalten reproduzieren?

2. Ist das ein Bug in der Implementation von system unter Win32 oder
übersehe ich da was?

3. Geht es dort beim Aufruf von der Kommandozeile, d.h. kann man sowas wie
$ ./foo 'arg=a&c' 'd'
an der Kommandozeile aufrufen, so daß das erste Argument korrekt
ankommt?

4. Wie ruft man unter Win32 aus Perl ein externes Kommando mit
Argumenten, die '&' enthalten sollen?



[1]: Siehe z.B. http://www.cpantesters.org/cpan/report/7053795. Der
relevente Teil meines Testskriptes lautet:

my $link =
'http://openstreetmap.org/?lat.692&lon=-17.448&zoom&layersB000FTF';

my $res = system($downloadosmtiles,
"--link=$link", "--zoom:13",
"--quiet", "--destdir=$testdir");
is($res, 0, "return value from downloadosmtiles.pl");
 

Lesen sie die antworten

#1 ekkehard.horner
05/04/2010 - 10:19 | Warnen spam
Rolf Krahl schrieb:
Ich möchte ein externes Programm mit system aufrufen und dabei
Kommandozeilenargumente übergeben, die '&' enthalten. Testbeispiel:



[...]
Windows braucht ":

#! /usr/bin/perl

use strict;
use warnings;

use English;

my @parms = ( './showargs.pl', 'arg=a&c', 'd' );

if ( $OSNAME =~ m/^mswin/i ) {
@parms = map { "\"" . $_ . "\"" } @parms;
}
printf "%s: |%s|", $OSNAME, join '|', @parms;
system @parms;

Ausgabe:

./useshowargs.pl
linux: |./showargs.pl|arg=a&c|d|
arg=a&c:d

perl -w useshowargs.pl
MSWin32: |"./showargs.pl"|"arg=a&c"|"d"|
arg=a&c:d

Ähnliche fragen