2009-11-19 3 views
5

Je veux écrire un script foo qui appelle simplement bar avec les mêmes arguments avec lesquels il a été appelé, en utilisant Bash ou Perl.Comment puis-je obtenir des arguments de ligne de commande non modifiés pour "envelopper" un autre outil de ligne de commande?

Maintenant, une simple façon de le faire en Perl serait

#!/bin/perl 

my $args=join(' ', @ARGV); 
`bar $args`; 

Cependant, les valeurs ARGV ont déjà été traitées par le shell, donc si je l'appelle

foo "I wonder, \"does this work\"" 

bar serait être appelé comme ça

bar I wonder "does this work" 

Comment puis-je obtenir la ligne de commande d'origine de sorte que je peux simplement le transmettre textuellement?

Répondre

11

Vous ne pouvez pas obtenir les arguments de l'exécutable perl avant qu'ils ne soient traités par le shell. Vous pouvez cependant faire en sorte que la coquille ne les traite pas à nouveau:

system('bar', @ARGV); 

contre

system("bar @ARGV"); 

Voir perldoc -f system:

S'il n'y a qu'un seul scalaire argument, l'argument est vérifié pour les métacaractères shell, et s'il y en a, l'argument entier est passé à shell de commande pour l'analyse (c'est "/ bin/sh -c" sur les plates-formes Unix, mais varie sur d'autres plates-formes). S'il n'y a pas de métacaractères shell dans l'argument , il est divisé en mots et transmis directement à "execvp", ce qui est plus efficace.

Si vous avez besoin de lire la sortie du programme, utilisez une poignée de processus et de transmettre les arguments de la même manière (sans interpolation):

open my $barhandle, '-|', 'bar', @ARGV or die "Can't call bar: $!"; 
while (my $line = <$barhandle>) 
{ 
    # do something with $line... 
} 
close $barhandle; 

Il y a beaucoup de façons dont vous pouvez appeler à un programme en Perl; Voir What's the difference between Perl's backticks, system, and exec? pour un bon aperçu des principales options.

+0

Une considération étant, bien sûr, que la valeur de retour de system() est la valeur de retour de l'exécution du programme, pas la sortie du programme. Il peut être nécessaire de rediriger la sortie vers un fichier et de lire le fichier, si vous essayez de collecter sa sortie. – atk

+0

@atk: dans ce cas, vous pouvez utiliser un handle de processus. – Ether

+1

non, dans ce cas, vous utilisez IPC :: Run ou IPC :: Cmd – ysth

3

C'est extrêmement simple. Consultez la variante système (LIST) des appels système.

system('bar', @ARGV); 

système perldoc -f

3

En bash:

exec bar "[email protected]" 

Cela préserve l'espacement des arguments. Toutefois, la redirection d'E/S n'est pas un argument au sens du terme (mais la redirection d'E/S effectuée pour l'invocation d'origine persisterait jusqu'à la commande 'bar' invoquée sauf si vous la modifiez).

Questions connexes