Por que aceita switches duplicados?

16

Estou curioso - existe uma diferença entre ls -le ls -lllllllllllllllllllllllllllll?

A saída parece ser a mesma e estou confuso sobre o porquê de lspermitir opções duplicadas. Essa é uma prática padrão entre a maioria dos comandos?

Mike B
fonte

Respostas:

17

Resposta curta :

Porque está programado para ignorar vários usos de um sinalizador.

Resposta longa:

Como você pode ver no código fonte de ls, há uma parte com a função getopt_long()e um enorme gabinete de chave:

1648       int c = getopt_long (argc, argv,
1649                            "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
1650                            long_options, &oi);
      ....
1654       switch (c)
1655         {
      ....
1707         case 'l':
1708           format = long_format;
1709           break;
      ....
1964     }

A função getopt_long()lê todos os parâmetros dados ao programa. Caso -la variável formatesteja definida. Portanto, quando você digita múltiplo, -lllllllllessa variável é definida várias vezes, mas isso não muda nada.

Bem, isso muda uma coisa. Essa declaração enorme de caso de switch deve ser executada várias vezes, devido a vários -lsinalizadores. lsprecisa de mais tempo para concluir com vários -lsinalizadores. Mas desta vez não vale a pena mencionar. =)

caos
fonte
11
Ou, dito de outra maneira, rejeitá-los seria mais trabalho para o programador do que ignorá-los.
Mark
11
+0,5 por dizer o que eu ia dizer, +0,5 por ir para a fonte.
um CVn
21

Porque é a coisa certa a fazer. Suponha que você tenha um script fazendo algo como:

ls $LS_OPTIONS -l "$dir"

onde é possível que $LS_OPTIONSjá contenha -l. Seria contra-intuitivo e irritante para esse comando produzir um erro e exigiria lógica extra no script para evitá-lo.

-lpode não ser o melhor exemplo disso, mas espero que você possa ver como o conceito se aplica em geral. Um exemplo muito melhor são as opções do compilador $CFLAGSque podem duplicar opções explícitas em uma chamada específica do compilador.

R .. GitHub PARE DE AJUDAR O GELO
fonte
4
O mesmo poderia acontecer se você tivesse definido um alias que chama lscom algum conjunto de opções.
kasperd
11
@kasperd: Sim. Embora colocar -lseu lsalias pareça uma má ideia, é provável que o mesmo problema ocorra com as opções que são boas em um lsalias interativo como -pou --color=auto.
R .. GitHub Pare de ajudar o gelo
11
O alias não precisa ser chamado ls. llpode ser um alias para ls -l, e em um sistema com esse alias, eu poderia digitar ll -lart.
kasperd
11

lsnão é um bashcomando, mas um executável separado do qual você inicia bash. Dito isto, -lé apenas um tipo de sinalizador booleano que, se presente, faz lscom que use um formato de estilo longo para a saída. A maioria dos programas simplesmente ignora vários usos ( ls -llé o mesmo que ls -l -l) desses sinalizadores, embora existam algumas exceções (por exemplo, se -vsignifica 'detalhado', um programa pode interpretar vários usos para significar "ser ainda mais detalhado").

chepner
fonte
2
Um exemplo de -vvvé ssh.
Bernhard
Ou até mesmoaptitude moo
Ruslan
8

Os aliases do shell seriam muito irritantes se comandos como lsnão permitissem opções repetidas.

Suponha que você tivesse

alias ls='ls --color=auto'
alias rm='rm -i'

Se não fossem permitidos sinalizadores conflitantes, seria um erro emitir comandos como ls --color=neverou ls --color=autoou rm -i.

Portanto, esses comandos foram projetados para permitir que sinalizadores posteriores substituam os sinalizadores anteriores.

200_success
fonte
Às vezes, opções conflitantes não são permitidas. (Tente o rsync com os dois --inplacee --delay-updates, por exemplo.) Algumas ferramentas apenas aceitam o que vier por último; rm -ifprovavelmente é um bom exemplo lá. Mas não há conflito na opção -l das ls, portanto, ls -le ls -llnão é um problema, e não afeta a execução de qualquer maneira significativa. Os computadores são bons em repetições entorpecentes.
um CVn