En utilisant Getopt :: long pour conduire une commande système sous Linux
-
14-10-2019 - |
Question
Je suis en train d'exécuter un script php avec des arguments, en utilisant le pilote perl suivant:
#!/opt/local/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Cwd;
my %args = ();
GetOptions(
\%args, "NUM_AGENTS|a=s",
"HOST_NAME|h=s", "TIME_STAGGER|t=s",
"USER_NAME|un=s", "USER_PASS|pw=s",
"TARGET_PAGE|p=s"
) or die "Unknown parameter!\n";
my $i = 0;
my $startTime = time;
my $pwd = getcwd();
my $logdir = "$pwd/load-logs";
mkdir $logdir
or die "Cannot mkdir $logdir: $!"
unless -d $logdir;
chmod 0755, $logdir or die "Cannot chmod 0755 $logdir: $!";
my $startTimeTemp = $args{NUM_AGENTS} + $startTime;
my $startTime2 = $startTimeTemp + 10;
mkdir( "$logdir/$startTime2", 0777 )
or die "Cannot mkdir $logdir/$startTime2: $!"
unless -d "$logdir/$startTime2";
my $random_number = rand() * 10;
my $execDelay =
( $random_number % $args{TIME_STAGGER} ) * ( ( $random_number % 100 ) );
my $procStartTime = $startTime2 + $execDelay;
my $reqlogfile = "$logdir/$startTime2/req.log";
my $resplogfile = "$logdir/$startTime2/resp.log";
print "NUM_AGENTS: " . "$args{NUM_AGENTS}\n";
print "HOST_NAME: " . "$args{HOST_NAME}\n";
print "procStartTime: " . "$procStartTime\n";
print "i: " . "$i\n";
print "TARGET_PAGE: " . "$args{TARGET_PAGE}\n";
print "resplogfile: " . "$resplogfile\n";
print "USER_NAME: " . "$args{USER_NAME}\n";
print "USER_PASS: " . "$args{USER_PASS}\n";
print "execDelay: " . "$execDelay\n";
print "COMMON_SID: " . "$args{COMMON_SID}\n";
while ( $args{NUM_AGENTS} > $i ) {
$i++;
print "count: " . "$i\n";
my $argString =
"'$args{NUM_AGENTS}' '$args{HOST_NAME}' '$procStartTime' '$i' '$args{TARGET_PAGE}' 'resplogfile' '$reqlogfile' '$args{USER_NAME}' '$args{USER_PASS}' '$execDelay' '$args{COMMON_SID}'";
system("php loadAgent_curl.php $argString") == 0 or die "failed to execute: $!";
sleep 1;
#system("ls");
}
mais il semble que quelque chose ne va pas avec:
system("php loadAgent_curl.php $argString")
depuis les commandes du système ls fonctionne très bien, mais la commande php avec des arguments ne pas
Les arguments de ligne de commande ot ce script Perl peut être:
-a 10 -h ktest.test.net t5 -UN admin -pw adminpassword -p "acViewer / index.html? StartDate = 20090926040000 & EndDate = 20111220235959"
La solution
Vous ne mentionne pas le type de message d'erreur que vous obtenez. Est-ce quelque chose comme Cannot find "php"
ou autre chose.
Vous pourriez avoir des difficultés avec des guillemets. Voici quelques recommandations:
- Utiliser
qq()
au lieu de guillemets. Ça va rendre les choses un peu plus propre. - Construire la commande dans une variable appelée
$command
que vous pouvez imprimer dans le cas où vous avez des erreurs. Cette aide pourrait vous comprendre où vous avoir peut-être un problème. - Définir une variable appelée
$error
lors de l'exécutionsystem
, puis vérifier cette variable. Il est beaucoup plus clair que le style de l'arrière trucsand/or
que vous devez faire en cas d'échec et de succès, et il est beaucoup plus facile à entretenir.
Exemple:
my $argString = qq("$args{NUM_AGENTS}" "$args{HOST_NAME}" )
. qq( "$procStartTime" "$i" "$args{TARGET_PAGE}" "resplogfile" )
. qq("$reqlogfile" "$args{USER_NAME}" "$args{USER_PASS}" )
. qq("$execDelay" "$args{COMMON_SID}");
my $command = qq(php loadAgent_curl.php $argString);
my $error = system qq($command);
if ($error) {
die qq(ERROR: Failed to execute "$command"\n\n$!);
}
Au moins de cette façon, vous pouvez voir ce que la commande a échoué, et avoir une meilleure idée pourquoi il pourrait ne pas avoir exécuté.
Autres conseils
Contrairement à la plupart des autres commandes Perl, system
retourne 0 sur « succès » et non nul sur « l'échec ». Donc, l'idiome typique est
system $command and die ...
au lieu de
system $command or die ...
Mise à jour :. L'OP a fait obtenir ce droit partiel - system(...)==0 or die ...
est aussi une façon parfaitement bien faire la vérification des erreurs sur la commande system
Il pourrait également être une géniale citation dans la commande exacte que vous passez à la commande system
. Pour une telle tâche, il est souvent préférable de contourner la coquille et utiliser le formulaire LIST de system
pour passer la commande directement à l'OS. Peut-être quelque chose comme:
my @argList = ($args{NUM_AGENTS}, $args{HOST_NAME}, $procStartTime, $i,
$args{TARGET_PAGE}, 'resplogfile', $reqlogfile, $args{USER_NAME},
$execDelay, $args{COMMON_SID});
system("php", "loadAgent_curl.php", @argList) and die "failed to execute: $!";
(et assurez-vous php
est dans votre $PATH
[ou spécifier le chemin complet vers php
] et loadAgent_curl.php
est dans le répertoire courant).
Essayez PHP - GetOptionKit:
http://c9s.blogspot.com/2011/11/php- getoptionkit.html
synopsis
use GetOptionKit\GetOptionKit;
$getopt = new GetOptionKit;
$spec = $getopt->add( 'f|foo:' , 'option require value' ); # returns spec object.
$getopt->add( 'b|bar+' , 'option with multiple value' );
$getopt->add( 'z|zoo?' , 'option with optional value' );
$getopt->add( 'f|foo:=i' , 'option require value, with integer type' );
$getopt->add( 'f|foo:=s' , 'option require value, with string type' );