2009-11-19 17 views
5

Quiero escribir un script foo que simplemente llame a bar con exactamente los mismos argumentos con los que fue llamado, usando Bash o Perl.¿Cómo puedo obtener argumentos de línea de comandos no modificados para "ajustar" otra herramienta de línea de comandos?

Ahora, una forma sencilla de hacer esto en Perl sería

#!/bin/perl 

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

Sin embargo, los valores en ARGV ya han sido procesados ​​por el shell, por lo tanto si llamar

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

barra haría llamarse así

bar I wonder "does this work" 

¿Cómo puedo obtener la línea de comando original para que simplemente pueda pasarlo? ¿literal?

Respuesta

11

No se pueden obtener los argumentos del ejecutable de perl antes de que el shell los haya procesado. Puede, sin embargo, asegurar que el depósito no los procesa de nuevo :

system('bar', @ARGV); 

vs

system("bar @ARGV"); 

Ver perldoc -f system:

Si hay único escalar argumento, el argumento se verifica para los metacaracteres del shell, y si hay alguno, el argumento completo se pasa al del sistema shell de comandos para el análisis (esto es "/ bin/sh -c" en plataformas Unix, pero varía en otras plataformas). Si no hay metacaracteres de shell en el argumento , se divide en palabras y se pasa directamente a "execvp", que es más eficiente.

Si necesita leer la salida del programa, utilizar un identificador de proceso y pasar los argumentos de la misma manera (sin interpolación):

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

Hay un montón de maneras que usted puede llamar a cabo a un programa en Perl; ver What's the difference between Perl's backticks, system, and exec? para una buena descripción de las opciones principales.

+0

Una consideración es, por supuesto, que el valor de retorno de system() es el valor de retorno de la ejecución del programa, no el resultado del programa. Puede ser necesario redirigir el resultado a un archivo y leer el archivo, si está intentando recopilar su resultado. – atk

+0

@atk: en ese caso, puede usar un identificador de proceso. – Ether

+1

no, en ese caso usted usa IPC :: Run o IPC :: Cmd – ysth

3

Es extremadamente simple. Consulte la variante del sistema (LISTA) de las llamadas al sistema.

system('bar', @ARGV); 

sistema perldoc -f

3

En bash:

exec bar "[email protected]" 

Esto preserva la separación en los argumentos. Sin embargo, la redirección de E/S no es un argumento dentro del significado del término (pero la redirección de E/S hecha para la invocación original persistiría en el comando invocado 'bar' a menos que lo modifique).

Cuestiones relacionadas