Por que a opção “argumento pode ser esmagado contra” prevalece sobre “o argumento é sempre separado”?

5

Inspirado pela recente pergunta Por que a seqüência específica de opções é importante para o comando tar? , em que o perguntado por que tar -cfv test.tar *.jpg não funciona, eu gostaria de perguntar: seriamente, por que não?

Quando um comando tem uma opção -f que requer um argumento e uma opção -v que não, isso:

cmd -fv foo

pode ser interpretado de 2 maneiras diferentes: o v é o argumento para a opção -f e foo é um argumento não opcional, ou foo é o argumento para a opção -f e A opção -v está presente. A primeira interpretação é o que POSIX getopt() faz, então existem muitos comandos que se comportam dessa maneira.

Eu sempre preferi a segunda interpretação. Empacotando todas as opções juntas (independentemente de elas levarem argumentos) parece mais útil do que esmagar o foo contra o -f para transformar -f foo em -ffoo . Mas esse comportamento quase não existe mais. O único comando que usei recentemente é o jar do Java (que tem uma sintaxe claramente inspirada por essa versão do Sun de tar que aceita tar cfv tarfile ... ).

O Xlib tem uma função getopt -like, XrmParseCommand , que permite que as opções sejam especificadas como argumentos "separados" ou argumentos "fixos". Mas ele lida com opções longas ( -display , -geometry , etc.), portanto, ele vê -fv como apenas outra opção sem relação para -f ou -v . Então não é um exemplo da minha segunda interpretação.

Quando e por que os squished args se tornam dominantes? Já foi resolvido antes do POSIX, ou o mandato do POSIX resolveu o problema? A primeira versão do POSIX ainda tem o mesmo requisito específico da versão atual? Existe alguma discussão arquivada do assunto desde os tempos antigos?

Existem outros comandos (além de tar e jar ) que suportam ou historicamente suportam o estilo -fv foo = -f foo -v de análise de opções?

    
por Wumpus Q. Wumbley 04.03.2015 / 03:48

1 resposta

6
Primeiro de tudo, no processamento padrão de argumentos no estilo getopt() , os argumentos não precisam ser esmagados contra a opção à qual eles se aplicam, eles simplesmente podem ser. Portanto, se -f receber um argumento, ambos os seguintes serão válidos:

command -ffoo positional arguments
command -f foo positional arguments

O que você chama de "segunda interpretação" é, na verdade, muito, muito raro. Tanto quanto eu posso pensar agora, tar e mt são os únicos comandos existentes que funcionam dessa forma ... e, como você mencionou, jar , mas isso é só porque ele emula tar . Esses comandos processam argumentos de maneira muito diferente do padrão getopt() -style. As opções nem são precedidas por - ! Eu não posso dizer com certeza por que isso raramente era usado, mas eu acho que é por causa do fato de que é mais difícil dizer quais opções combinam com quais argumentos. Por exemplo, se b e d receberem argumentos, mas a , c e e não, você tem isso:

command abcde b-argument d-argument

... o que significa que enquanto você estiver compondo o comando, você deve olhar para o grupo de letras de opção, lê-lo novamente, lembrar quais opções você especificou requerem argumentos e escrever os argumentos na mesma ordem. O que sobre isso?

command adcbe b-argument d-argument

Opa, a opção d obteve o b-argument e vice-versa. Pior, se você ver:

command lmnop foo bar baz

... e você não está familiarizado com o comando, você não tem idéia de quais argumentos vão com quais opções. foo , bar e baz podem ser argumentos para n , o , p (e l e m não recebem argumentos) ou foo e bar podem ir com, digamos, m e p , enquanto baz é um parâmetro posicional ... ou muitas outras combinações possíveis.

    
por 04.03.2015 / 05:43