Pasar argumentos de un archivo a un script bash


10

Tengo esta situación:

./
./myscript.sh
./arguments.txt
./test.sh

Dentro myscript.sh, tengo que ejecutar el archivo test.sh, pasándole los argumentos contenidos dentro arguments.txt.

myscript.sh es:

arguments=$(cat arguments.txt)
source test.sh $arguments

Esto funciona bien si if argumentos.txt contiene como máximo un argumento:

firstargument 

La sustitución es:

++ source test.sh 'firstargument'

Pero el problema es con dos o más argumentos. Hace esto:

++ source test.sh 'firstargument secondargument'

Además, no sé de antemano la cantidad de argumentos que contiene arguments.txt. Puede haber cero o más.


Lo que está describiendo no es el comportamiento predeterminado de bash. ¿Realmente estás usando bash, o algún otro shell (como zsh, que hará esto)?
Patrick

@Patrick Hola, es una verdadera fiesta. Por cierto, ya tengo la respuesta gracias de todos modos!
Federico Ponzi

¿En realidad estás escribiendo source test.sh "$arguments"con citas? Esa sería una explicación para su descripción
Glenn Jackman

Intenté con y sin comillas dobles. Con la sustitución de bash siempre obtengo la cita única. Entonces source test.sh "$arguments"y source test.sh $argumentsambos resultan en source test.sh 'firstargument secondargument'.
Federico Ponzi

Respuestas:


6

Suponiendo que cada línea de arguments.txtrepresenta un argumento separado, con bash 4 puede leer arguments.txten una matriz usando mapfile(cada línea del archivo entra como un elemento de la matriz, en secuencia) y luego pasar la matriz al comando

mapfile -t <arguments.txt
source test.sh "${MAPFILE[@]}"

La ventaja es que se evita la división en espacios incrustados dentro de las líneas

Con versiones inferiores de bash

IFS=$'\n' read -ra arr -d '' <arguments.txt
source test.sh "${arr[@]}"

Dentro del archivo argumentos.txt los argumentos están separados por espacio. Por cierto, intenté algo muy similar usando array y a pero no funcionó y no sé por qué. Pues muchas gracias!
Federico Ponzi

2

Puedes hacer esto con awk. Por ejemplo:

arguments=`awk '{a = $1 " " a} END {print a}' arguments.txt`

Edite después de leer su comentario:

arguments=`awk '{i = 0; while(i<=NF){i++; a = a " "$i}} END {print a}'

1

Sugeriría usar una función con un ciclo while / do para recorrer el archivo de argumentos.

Simplemente cree un archivo que contenga la función y luego llame al archivo test.sh dentro de la función para iterar a través de los argumentos contenidos en el archivo argumentos.txt.

#!/bin/sh
# Calling script

function_name ()
  {
    while read line;
      do
        . ~/path_to/test.sh $line
         do_something_commands # print to screen or file or do nothing
      done < ~/path_to_/argument_file.txt
  }

function_name # Call the function
  do_something_commands # print to screen or file or do nothing
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.