BASH: diferença entre flags com - e com --
Por que comandos às vezes recebem argumentos por meio de - e às vezes com --? Existe uma explicação/padrão/convenção, ou é totalmente aleatório?
Por que comandos às vezes recebem argumentos por meio de - e às vezes com --? Existe uma explicação/padrão/convenção, ou é totalmente aleatório?
É apenas uma convenção (uma regra que muitos adotaram e que acabou sendo disseminada). Não é obrigatório, mas se vc fizer diferente com certeza causará estranheza com quem está acostumado.
A convenção é que opções que são compostas por apenas um caractere são precedidas por um hífen (como ls -l
, por exemplo). E existe a possibilidade de combinar mais de uma opção, ou seja, em vez de ls -a -l
, posso fazer ls -al
.
Já as opções longas (com mais de um caractere) foram criadas muitas vezes para dar mais clareza (já que correspondem a palavras completas), e convencionou-se usar dois hífens antes delas (como ls --help
).
Alguns comandos possuem ambas as alternativas para muitas opções. Por exemplo, a saída de ls --help
mostra algumas delas:
-a, --all do not ignore entries starting with .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
-b, --escape print C-style escapes for nongraphic characters
--block-size=SIZE with -l, scale sizes by SIZE when printing them;
-c with -lt: sort by, and show, ctime (time of last
modification of file status information);
with -l: show ctime and sort by name;
otherwise: sort by ctime, newest first
Ou seja, ls -a
seria o mesmo que ls --all
. Já a opção -c
não possui um equivalente "longo".
Repare que também seria possível fazer ls -all
, mas aí estamos passando a opção -a
mais a opção -l
duas vezes, que além de redundante, é diferente de usar --all
(pois este é equivalente a passar apenas a opção -a
). O uso dos dois hífens faz toda a diferença.
Ah, então mesmo tendo nascido como convenção, hoje o bash já entende que comandos com -- devem ser lidos de forma completa e única, o que permite a diferença entre -all e --all ou de comandos que incluam o - no nome, como o --save-dev do npm, além de evitar erros como, por exemplo, ao passar um -name do docker run, porque ele não reconhece -n, -m nem -e como flags? Se sim, então significa que o -it do docker na vdd pode ser passado como -i -t?
ao passar um -name do docker run, porque ele não reconhece -n, -m nem -e como flags?
Ele até reconhece -a
, -m
e -e
, mas dá erro porque a opção -n
não existe, veja na documentação.
então significa que o -it do docker na vdd pode ser passado como -i -t?
Sim.
hoje o bash já entende
Não é exatamente o Bash, cada comando lê as opções e as interpreta da forma que quiser. O que acontece é que muitos usam alguma biblioteca padrão (seja POSIX ou extensões da GNU, por exemplo), que possui funções prontas para interpretá-los da forma que expliquei. Se não me engano, são as extensões da GNU que adicionaram o suporte à forma longa.
Mas nada impede que eu faça um programa que aceita opções em um formato completamente diferente.
No caso de CLI feitas em python a biblioteca padrão da linguagem tem uma lib chamada argparse que consegue manipular os argumentos de forma "automatica" e também tem uma interface legal pra criar a documentação sem grandes esforços