Passando argumentos de um arquivo para um script bash


10

Eu tenho essa situação:

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

Por dentro myscript.sh, tenho que executar o arquivo test.sh, passando para ele os argumentos contidos nele arguments.txt.

myscript.sh é:

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

Isso funciona bem se if.txt contiver no máximo um argumento:

firstargument 

A substituição é:

++ source test.sh 'firstargument'

Mas o problema está em dois ou mais argumentos. Faz o seguinte:

++ source test.sh 'firstargument secondargument'

Além disso, não sei de antemão o número de argumentos internos arguments.txt. Pode haver zero ou mais.


O que você está descrevendo não é o comportamento padrão do bash. Você está realmente usando o bash ou algum outro shell (como o zsh, que fará isso)?
Patrick

@ Patrick Oi, é bash real. Btw eu já tenho a resposta obrigado de qualquer maneira!
Federico Ponzi

Você está realmente escrevendo source test.sh "$arguments"com aspas? Isso seria uma explicação para sua descrição
Glenn Jackman

Eu tentei com e sem aspas duplas. Com a substituição do bash, eu sempre recebo a citação única. Então, source test.sh "$arguments"e source test.sh $argumentsambos resultam em source test.sh 'firstargument secondargument'.
Federico Ponzi

Respostas:


6

Assumindo que cada linha de arguments.txtrepresenta um argumento separado, com o bash 4 você pode ler arguments.txtem uma matriz usando mapfile(cada linha do arquivo entra como um elemento da matriz, em sequência) e depois passa a matriz para o comando

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

A vantagem é que é evitada a divisão em espaços incorporados nas linhas

Com versões inferiores do bash

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

Dentro do arquivo argumentos.txt, os argumentos são separados por espaço. Btw eu tentei algo muito semelhante usando matriz e um para, mas não funcionou e não sei por que. Bem, muito obrigado!
Federico Ponzi

2

Você pode fazer isso com awk. Por exemplo:

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

Edite depois de ler seu comentário:

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

1

Eu sugeriria o uso de uma função com um loop while / do para percorrer o arquivo de argumento.

Basta criar um arquivo contendo a função the e, em seguida, chame o arquivo test.sh na função para iterar pelos argumentos contidos no arquivo 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.