Como faço para corrigir o argumento recebido do getopt?

Como faço para corrigir o argumento recebido do getopt?

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 getoptfoi 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 -sopçã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 getoptsnão requer evale é 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

informação relacionada