Como corrijo o argumento recebido de getopt?

4

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 faço para formatar corretamente o argumento?

    
por asheeshr 28.09.2013 / 05:21

1 resposta

7

O bash builtin getopts é muito mais fácil de usar. Se você estiver usando bash , você deve usá-lo em vez de getopt .

O GNU getopt foi projetado para trabalhar com argumentos que possuem espaços em branco e outros metacaracteres neles. Para fazer isso, ele produz uma string de resultado com aspas no estilo bash (ou aspas no estilo csh, dependendo da opção -s ). Você precisa organizar as cotas interpretadas, o que requer o uso de eval . (Eu mencionei que o bash construído em getopts é melhor?).

O exemplo a seguir é da distribuição getopt; Eu não tive nada a ver com isso. (Ele deve estar presente em sua máquina em algum lugar; com o Ubuntu e debian, ele aparece como /usr/share/doc/util-linux/examples/getopt-parse.bash . Estou citando apenas 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 que o comentário do exemplo aponta, é importante analisar o eval , que geralmente é desaprovado.

Por outro lado, o bash builtin 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
    
por 28.09.2013 / 06:00