Analisando argumentos aninhados

0

Não consigo analisar os argumentos de um script corretamente. O cenário é explicado abaixo.

Primeiro script (test2.sh):

#! /bin/sh
arg_part1="./test1.sh '123 789'"
arg_part2=456

#Option 1
${arg_part1} ${arg_part2} 

#Option 2
$("$arg_part1" arg_part2)

Segundo script (test1.sh):

#! /bin/sh
echo "Hello World $1 $2"

Saída:

Hello World '123 789'
./test1.sh '123 789': No such file or directory

Saída desejada:

Hello World 123 789 456

O '123 789' deve ser processado como primeiro argumento e 456 deve ser meu segundo argumento. Nota: não tenho a opção de dividir arg_part1 em duas variáveis diferentes.

    
por sbanik 16.11.2017 / 17:08

2 respostas

2

Eu acho que você está "preso" precisando usar eval aqui, então arg_part1 é reinterpretado como uma string de comando, que é então analisada em um comando e argumentos:

#! /bin/sh
arg_part1="./test1.sh '123 789'"
arg_part2=456
eval "${arg_part1}" "${arg_part2}"

Saída:

Hello World 123 789 456

Saída de depuração:

$ sh -x test2.sh
+ arg_part1='./test1.sh '\''123 789'\'''
+ arg_part2=456
+ eval './test1.sh '\''123 789'\''' 456
++ ./test1.sh '123 789' 456
Hello World 123 789 456

Observe que, como você citou aspas internas em '123 789' , elas aparecem como um único argumento $1 para test1.sh.

    
por 16.11.2017 / 17:16
3

Você pode continuar usando o operador split + glob (aqueles sem coeficiente ${arg_part1} e ${arg_part2} ), mas use um separador diferente para a parte dividida (pois alguns dos elementos contêm um dos separadores padrão (espaço)). Você também deseja desativar a parte glob.

#! /bin/sh
arg_part1='./test1.sh|123 789'
arg_part2=456

IFS='|'  # split unquoted expansions on | instead of default SPC+TAB+NL
set -o noglob # disable the glob part (not that it would have any effect
              # in this particular case).

$arg_part1 $arg_part2 # invoke split+glob

# or since you're not intending to split $arg_part2
$arg_part1 "$arg_part2"

Para armazenar código, as funções geralmente são mais apropriadas que as variáveis:

arg_part1() { ./test1.sh '123 789' "$@"; }
arg_part2=456

arg_part1 "$arg_part2"

e você não precisa se atrapalhar com o operador split + glob ou usar o perigoso eval .

    
por 16.11.2017 / 18:18