Por que essas opções aninhadas em um script de shell POSIX estão sendo divididas por palavras?

2

Eu tenho um script count_args que conta argumentos:

#!/bin/sh
echo $#

Se eu chamar com essas opções, ele me diz que recebe dois argumentos:

$ ./count_args --options '1 2'
2

Mas se eu construir os argumentos em um script test_args da seguinte forma:

#!/bin/sh
ARGS="--options '1 2'"
./count_args ${ARGS}

... eu obtenho o resultado:

$ ./test_args 
3

Por que o '1 2' está sendo dividido no script? Como posso evitar isso de uma maneira compatível com POSIX, do script de chamada ? É possível ainda armazenar argumentos em variáveis de alguma forma para que eu possa separá-los em scripts mais complexos (por exemplo, tendo ARGS_1 e ARGS_2 )?

Observe que meu /bin/sh é dash .

    
por detly 14.02.2016 / 05:48

1 resposta

3

No seu primeiro caso, os argumentos passados para count_args foram interpretados pelo shell, o shell viu duas palavras --options e 1 2 então passou para count_args .

Com o segundo caso, entre aspas duplas, todos os caracteres, exceto $ e \ , são tratados como literais. É muito tarde para o shell interpretar as aspas simples, o shell viu o conteúdo de $ARGS variable como uma longa string --options '1 2' , todos os caracteres como literais e não têm significado especial para o shell.

O uso de ${ARGS} sem aspas duplas fez com que ele fosse submetido à divisão de campos e à expansão de nomes de arquivos. Com o valor padrão de IFS , você tem três palavras separadas: --options , '1 e 2' .

A melhor maneira de arquivar isso é usar "$@" :

#!/bin/sh

set -- --options '1 2'

./count_args "$@"
    
por 14.02.2016 / 08:32