Eu tenho um script count_args
que conta argumentos:
#!/bin/sh
echo $#
Se eu ligar 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
assim:
#!/bin/sh
ARGS="--options '1 2'"
./count_args ${ARGS}
... eu recebo o resultado:
$ ./test_args
3
Por que o '1 2'
ser está dividido no roteiro? Como posso evitar isso de 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 o meu /bin/sh
é dash
.
Responder1
No seu primeiro caso, os argumentos passados para count_args
foram interpretados pelo shell, o shell viu duas palavras --options
e 1 2
depois as passou para count_args
.
No segundo caso, entre aspas duplas, todos os caracteres, exceto $
e, \
são tratados como literais. É tarde demais para o shell interpretar as aspas simples, o shell viu o conteúdo da $ARGS
variável como uma string longa --options '1 2'
, todos os caracteres como literais e não têm nenhum significado especial para o shell.
O uso ${ARGS}
sem aspas duplas o submeteu à divisão de campos e expansão de nome de arquivo. Com o valor padrão de IFS
, você tem três palavras separadas --options
:, '1
e 2'
.
A melhor maneira de arquivar isso é usando "$@"
:
#!/bin/sh
set -- --options '1 2'
./count_args "$@"