O getopts lê os argumentos da linha de comando em alguma ordem?

0

O manual do Bash diz

getopts optstring name [args]

When the end of options is encountered, getopts exits with a return value greater than zero. OPTIND is set to the index of the first non-option argument and name is set to ?.

Isso significa que

  • getopts apenas lê em opções e argumentos de opção, mas não argumentos que não são opções nem argumentos de opção?

  • getopts não pode trabalhar com o caso em que na linha de comando, algumas opções são especificadas após alguns argumentos que não são opções nem argumentos da opção? Em outras palavras, getopts requer que argumentos que não são opções nem argumentos de opção sejam especificados após todas as opções e argumentos de opção?

Obrigado.

    
por Tim 21.07.2017 / 15:37

1 resposta

4

Sim, getopts é a ferramenta para analisar opções no modo POSIX (mesmo em bash , o shell GNU):

Em:

cmd -abc -dxx -e yy arg -f -g

(com um optspec de :abcd:e:fg )

-f e -g são argumentos regulares. getopts para nesse arg .

Geralmente, você faz:

while getopts...
  case...esac
done
shift "$((OPTIND - 1))"
echo Remaining arguments:
[ "$#" -eq 0 ] || printf ' - %s\n' "$@"

Se você quiser processar as opções da maneira GNU, onde as opções são consideradas após argumentos não-opcionais (exceto quando há um -- ou quando POSIXLY_CORRECT está no ambiente), você pode usar a implementação util-linux ou busybox de getopt (com uma API diferente). Esse também suporta opções longas. Isso não será portátil fora do Linux.

Você faz algo como:

parsed_opts=$(getopt -o abcd:e:fg -l long -- "$@") || usage
eval "set -- $parsed_opts"
for o do
  case $o in
    (-[abcfg]) echo "no-arg option: $o"; shift;;
    (--long) echo "long option"; shift;;
    (-[de]) printf '%s\n' "option $o with arg $2"; shift 2;;
    (--) shift; break;;
    (*) echo "never reached";;
  esac
done
echo Remaining args:
[ "$#" -eq 0 ] || printf ' - %s\n' "$@"

Note que haverá alguma reordenação nessas opções e seus argumentos serão removidos dos "argumentos restantes":

$ busybox getopt -o abcd:e:fg -l long -- -a foo bar -e x baz --l
 -a -e 'x' --long -- 'foo' 'bar' 'baz'
    
por 21.07.2017 / 15:51

Tags