Eu tenho um script com este uso:
myscript [options] positional-args... -- [fwd-params]
Como [options]
pode ter variantes longas ou curtas, gosto de usar arquivos getopt
. Mas estou tendo problemas.
Eu uso getopt
assim:
args=$(getopt -o a:,b --long alpha:,gamma -- "$@")
eval set -- "$args"
while : ; do
case "$1" in
-a | --alpha) a="$2" ; shift 2 ;;
-b ) b=true ; shift ;;
--gamma ) g=true ; shift ;;
-- ) shift ; break ;;
esac
done
positionals=()
while [ $# -gt 0 ] ; do
case "$1" in
* ) positionals+=("$1"); shift ;;
-- ) shift ; break ;;
esac
done
# What-ever is left in "$@" needs to be forwarded to another program
backend "$@"
Isso funciona muito bem se eu não tiver nenhum [fwd-params]
:
$ getopt -o a:,b -- -a 1 -b pos1 pos2
-a '1' -b -- 'pos1' 'pos2'
^-- getopt adds this to help me find
the end-of-options/start-of-positionals
Mas desmorona se o usuário definir algum arquivo [fwd-params]
. Aqui está minha saída desejada:
$ getopt -o a:,b -- -a 1 -b pos1 pos2 -- fwd1
-a '1' -b -- 'pos1' 'pos2' '--' 'fwd1'
^
\- I'll use this to delimit
the positional arguments
from the forwarding ones.
E aqui está o que eu realmente entendo. A intenção do usuário --
foi filtrada.
$ getopt -o a:,b -- -a 1 -b pos1 pos2 -- fwd1
-a '1' -b -- 'pos1' 'pos2' 'fwd1'
Qual é a melhor maneira de delimitar meus argumentos posicionais dos de encaminhamento?
Bem, se o usuário passar os argumentos
-a 1 -b pos1 pos2 -- fwd1
, getopt toma the--
como o marcador, tornando todos os argumentos seguintes não opções. Não é um argumento posicional em si aqui.Se você quiser que
--
apareça como está, seu usuário terá que adicionar explicitamente o marcador e outro--
depois para separar os dois conjuntos de posicionais, por exemplo:ou você pode prefixar o conjunto de caracteres de opção com a
+
para solicitar o comportamento POSIX, onde qualquer não opção marca o fim das opções. Dessa forma, o--
no seu exemplo não seria mais o marcador, mas sim um posicional em si:Mas observe que se você não tiver argumentos posicionais no primeiro conjunto, o usuário ainda precisará adicionar manualmente um total de dois
--
s:Eu provavelmente faria algo semelhante ao que o GNU Parallel faz e usaria alguma outra string fixa para separar os dois tipos de posicionais. Por exemplo, faça com que o script procure a
::
, saindo--
para getopt. Então o usuário digitaria-a 1 -b pos1 pos2 :: fwd1
(com ou sem--
):ou sem posicionais no primeiro set: