Eu tenho os seguintes comandos no meu script:
set -- `getopt -q agvc:l:t:i: "$@"`
...
while [ -n "$1" ]
do
-i) TIME_GAP_BOOT=$2
shift ;;
...
sleep $TIME_GAP_BOOT
Ao invocar o script com -i 2
, recebo o erro
sleep: invalid time interval `\'2\''
O que estou fazendo de errado? Como formato corretamente o argumento?
Responder1
O bash integrado getopts
é muito mais fácil de usar. Se você estiver usando bash
, você deve usá-lo em vez de getopt
.
GNU getopt
foi projetado para trabalhar com argumentos que contenham espaços em branco e outros metacaracteres. Para fazer isso, ele produz uma string de resultado com aspas no estilo bash (ou aspas no estilo csh, dependendo da -s
opção). Você precisa organizar para que as aspas sejam interpretadas, o que requer o uso de eval
. (Eu mencionei que o bash embutido getopts
é melhor?).
O exemplo a seguir é da distribuição getopt; Eu não tive nada a ver com isso. (Deve estar presente em algum lugar da sua máquina; com ubuntu e debian, aparece como /usr/share/doc/util-linux/examples/getopt-parse.bash
. Estou apenas citando algumas linhas:
# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
Além das citações apontadas pelo comentário do exemplo, é importante observar o eval
, que geralmente é desaprovado.
Por outro lado, o bash interno getopts
não requer eval
e é bastante simples; basicamente emula a chamada da biblioteca C padrão:
while getopts agvc:l:t:i: opt; do
case "$opt" in
i) TIME_GAP_BOOT=$OPTARG;;
# ...
esac
done