/ / Cómo pasar parámetros de línea de comando desde un archivo: linux, pipe, argumentos de línea de comando, cat, argv

Cómo pasar parámetros de línea de comando desde un archivo - linux, pipe, argumentos de línea de comandos, cat, argv

Tengo un programa en C que lee los argumentos de la línea de comandos de argv. ¿Es posible hacer una canalización para redirigir el contenido de un archivo como argumentos de línea de comando a mi programa? Supongamos que tengo un archivo arguments.dat con este contenido:

0 0.2 302 0

Y quiero que mi programa sea llamado con:

./myprogram 0 0.2 302 0

Intenté lo siguiente:

cat arguments.dat | ./myprogram

sin éxito.

Respuestas

5 para la respuesta № 1

Con la mayoría de los shells, puede insertar el contenido de un archivo en una línea de comando con $(<filename):

./myprogram $(<arguments.dat)

Si su shell no lo admite, entonces una de las formas más antiguas funcionará:

./myprogram $(cat arguments.dat)
./myprogram `cat arguments.dat`   # need this one with csh/tcsh

(Si conoce la diferencia entre los argumentos de la línea de comando y la entrada del archivo, ¿no? ¿Por qué esperaría incluir los argumentos de la línea de comando en un programa?)


11 para la respuesta № 2

xargs es tu respuesta:

cat arguments.dat | xargs ./myprogram

O más fácil:

xargs -a arguments.dat ./myprogram

Consulte el manual para las muchas maneras de personalizar xargs. Por ejemplo, puede leer línea por línea en lugar de por palabra, y puede usar los argumentos en reemplazos más complejos.


2 para la respuesta № 3

... es decir: las respuestas a continuación se aplican a los casos en que no sería aceptable para ./myprogram --first-argument "first value" ser cambiado en silencio ./myprogram --first-argument; ./myprogram "first value".

Si tus argumentos son literales de una línea.

Es decir, si su entrada se ve como:

--first-argument
first value
--second-argument
second value

y te refieres a esto para correr:

./myprogram --first-argument "first value" --second-argument "second value"

... entonces deberías usar (con bash 4.0 o posterior):

readarray -t args <arguments.dat
./myprogram "${args[@]}"

... o (también para bash 3.x):

args=( )
while IFS= read -r arg; do
args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"

Si sus argumentos están provistos de citas o de escape para distinguirlos

Es decir, si su archivo contiene algo como (tenga en cuenta que las nuevas líneas y los espacios sin comillas se comportan de manera idéntica aquí):

--first-argument "first value"
--second-argument "second value"

... y te refieres a esto para correr:

./myprogram --first-argument "first value" --second-argument "second value"

... entonces deberías usar:

args=( )
while IFS= read -r -d "" arg; do
args+=( "$arg" )
done < <(xargs printf "%s" <arguments.dat)

Si controlas tu formato de argumento

Utilice valores delimitados por NUL. Es decir, crea el archivo como tal:

printf "%s" "argument one" "argument two" >arguments.dat

... y analizarlo de la siguiente manera:

args=( )
while IFS= read -r -d "" arg; do
args+=( "$arg" )
done <arguments.dat
./myprogram "${args[@]}"

Esto funcionará con todo posible valores de argumento, incluso aquellos con líneas nuevas literales, comillas literales, barras invertidas literales u otros caracteres no imprimibles. (NULs literales no son posibles en las líneas de comando de UNIX, ya que las líneas de comando están compuestas por cadenas terminadas en NUL; por lo tanto, NUL es el único carácter que es completamente seguro de usar para separar de manera inequívoca argumentos en una cadena).


Si se desea dividir argumentos entre invocaciones

Esta subsección es relevante si el resultado deseado.(cuando hay más argumentos en su archivo que los que se pueden pasar a una invocación de su programa) hay varias invocaciones distintas del programa, cada una de las cuales recibe un subconjunto de argumentos. Esta es una familia de casos donde xargs Es la herramienta adecuada para el trabajo.

Si está en una plataforma GNU, es posible que desee ejecutar xargs -a arguments.dat en lugar de redirigir stdin; sin embargo, esto no es compatible con BSD xargs (como en MacOS), por lo que no se demuestra aquí.

Si tus argumentos son literales de una línea.

Con GNU xargs (la mayoría de las plataformas Linux):

xargs -d $"n" ./myprogram <arguments.dat

Con BSD xargs (MacOS, FreeBSD / OpenBSD / etc):

xargs -0 ./myprogram < <(tr "n" "" <arguments.dat)

Si sus argumentos están provistos de citas o de escape para distinguirlos

xargs ./myprogram <arguments.dat

Si ha generado entradas delimitadas por NUL

xargs -0 ./myprogram <arguments.dat