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?

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. =)


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.


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").


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.


À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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.