Estilo de opções da linha de comando - POSIX ou o quê?

16

Em algum lugar, vi um discurso retórico contra java / javac, usando uma mistura de estilos Windows e Unix, como

java -classpath ... -ea ... Something

IMHO, não é uma mistura, é como findfunciona também, não é? AFAIK, de acordo com o POSIX, a sintaxe deve ser como

java --classpath ... --ea ... Something

e -abcdefsignificaria especificar seis opções curtas de uma só vez. Gostaria de saber qual versão leva, em geral, a menos digitação e menos erros.

Estou escrevendo um pequeno utilitário em Java e, em nenhum caso, vou usar o estilo Windows, /a /bpois estou interessado principalmente no Unix. Que estilo devo escolher?

maaartinus
fonte
1
O POSIX 1003.1-2003, Definições de Base, Capítulo 12, Seção 2 fornece as seguintes diretrizes sobre a sintaxe da linha de comando do utilitário: "Cada nome de opção deve ser um único caractere alfanumérico (a classificação de caractere alnum) do conjunto de caracteres portáteis". e "Todas as opções devem ser precedidas pelo caractere delimitador '-'".
Greg A. Woods,

Respostas:

21

Você pode encontrar as convenções de argumentos POSIX no capítulo Convenções de Utilitários . O estilo POSIX consiste em opções com um único traço seguido por uma única letra indicando a opção, com o valor do argumento separado da opção por um espaço.

Existem exceções nas regras - findpor exemplo -, mas isso ocorre devido aos precedentes históricos do Unix.

O X Windows (X11) usa findopções de nome longo de traço único.

As opções de nome longo com traço duplo foram pioneiras no GNU (após um desvio usando +como prefixo).

Consulte esta pergunta StackOverflow para uma discussão sobre a grande variedade de sistemas conhecidos de manipulação de argumentos de linha de comando - existem muitos. ( Uma vez que este foi escrito, os poderes que-ser decidida a questão SO 367309 não foi um bom ajuste para SO. Eu já transferiu a resposta a outra pergunta, que é a sintaxe geral de um comando Unix shell? . )

Você pode estender a lista de técnicas para cobrir git(e vários outros sistemas) onde você obtém uma estrutura como:

  • basecommand[ opções globais ] subcommand[ opções de subcomando ] [nome ...]

Pode haver muitos subcomandos, cada um com seu próprio léxico de opções.

Obviamente, o Windows usa barra (usada) ' /' para indicar opções em vez de traço ' -'.

A JCL (para z / OS, OS / 360 e sistemas intermediários) tende a usar parâmetros posicionais separados por vírgulas e é geralmente considerada como não sendo amigável ou uma boa interface.

Jonathan Leffler
fonte
1
+1 Para os bons links e menção git.
Maaartinus
Gosto de todas as respostas, aceitei essa por causa dos links.
Maaartinus
A questão stackoverflow parece ter sido excluída (ou possivelmente movida) ... alguém sabe para onde foi? Estou curioso para ler.
Mizipzor
1
@ mizipzor: veja a atualização para a localização atual das informações. Veja também Opções curtas / longas com argumento de opção - isso é algum tipo de convenção?
Jonathan Leffler
"Obviamente, o Windows usa a barra (usada) '/' para indicar opções em vez de traço '-'." A maioria das ferramentas de linha de comando do Windows agora oferece suporte a ambos, e o PowerShell segue o caminho de usar apenas o traço.
Jpmc26
15

EDIT: Tem sido apontado que esse estilo é um GNU-ism, e que Unixes não baseados em GNU tendem a usar uma sintaxe de traço único (em particular, variantes do OS X e BSD).

Apesar do status de GNU-ism, muitos programas no estilo Unix recém-escritos usam este estilo:

  • --long-option para nomes de opções longos,
  • -s para opções curtas (um caractere),
  • -abc para várias opções curtas sem argumentos (um caractere por opção).
  • Opções com argumentos:
    • --long argou --long=argpara opções longas,
    • -s arg, -sargou (opcionalmente) -s=argpara opções curtas. Isso pode ser combinado com outras opções curtas, desde que apenas a última tenha um argumento.
  • A mesma opção "semântica" pode ter vários aliases, geralmente um curto (mais rápido para digitar) e um longo (mais fácil de lembrar).

Qualquer pessoa que use um shell Linux por um período de tempo deve estar familiarizado com esse estilo 1 , para que tenha o princípio de menos surpresa do seu lado. Permitir o agrupamento de várias opções curtas sem ser ambíguo com opções longas também é bom.

1 Por exemplo, alguns dos programas que utilizam este estilo (na minha máquina Linux): ls, grep, man, sed, bash, etc. ( EDIT: estes são aparentemente GNU-ismos porém, máquinas BSD e OS X não use este estilo)

Existem várias bibliotecas que podem cuidar disso para você analisar (a mais conhecida é a implementação do getopt do GNU ), apenas sendo necessário especificar quais opções longas e curtas existem, se elas levam um argumento e o que fazer quando um opção encontrada. (E, claro, o que fazer com argumentos posicionais, ou seja, aqueles que não começam com -e não são argumentos para as opções anteriores)

findé um programa muito antigo (ou talvez mais provável: uma versão reescrita de um programa muito antigo) que não pode ser facilmente alterado para usar uma nova sintaxe de linha de comando. Muitos scripts quebrariam e muitos usuários acostumados à sintaxe antiga reclamariam. javacprovavelmente foi influenciado por gcce amigos, que também seguem uma sintaxe antiga por razões históricas.

Frits
fonte
+1 - Além disso, quando você tem centenas de opções, você só precisa ser criativo (por exemplo, ao escrever um compilador)
Tim Post
1
Você dá a impressão de que todos os Unices usam utilitários GNU (por exemplo, dash-dash args) e isso está errado. O Mac OS X não oferece suporte a eles e o mesmo se aplica ao Free BSD.
Martin Wickman
8
  • O argumento com dash-dash ( --long-arg) é uma convenção GNU (veja a implementação getopt ).
  • Os comandos POSIX nunca usam argumentos de traço duplo. Isso se aplica à maioria das variantes do Unix (Mac OS X, BSD), exceto o Linux, que usa o GNU por padrão.

Para seu projeto Java, você pode conferir o GNU getopt for Java ou Apache CLI . Eles apóiam as duas convenções.

Uma terceira opção é usar argumentos da Java VM e deixar o tempo de execução analisá-los para você:

 $ java -Dcolor=blue

E então, no código:

 System.getProperty("color");

Pessoalmente, eu usaria o -Didioma e agruparia o encantamento Java em um script de shell que lida com a análise de linha de comando, incluindo a verificação do caminho de classe etc. Isso também facilita para os usuários nativos executar o seu programa Java.

Martin Wickman
fonte
1

Depende. Pessoalmente, prefiro o estilo POSIX, mas, no seu caso, provavelmente buscaria consistência com o ambiente em que sua ferramenta será usada. Isso significa usar a convenção Java para JARs (a menos que você planeje ter um script de wrapper que faça com que pareça um comando típico do Unix).

Adam Byrtek
fonte