Pourquoi ls accepte-t-il les commutateurs en double?

16

Je suis curieux - y a-t-il une différence entre ls -let ls -lllllllllllllllllllllllllllll?

La sortie semble être la même et je ne comprends pas pourquoi lsautorise les commutateurs en double. Est-ce une pratique standard parmi la plupart des commandes?

Mike B
la source

Réponses:

17

Réponse courte :

Parce qu'il est programmé pour ignorer les utilisations multiples d'un drapeau.

Longue réponse:

Comme vous pouvez le voir dans le code source de ls, il y a une partie avec la fonction getopt_long()et un énorme boîtier de commutation:

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     }

La fonction getopt_long()lit tous les paramètres donnés au programme. Dans le cas où -lla variable formatest définie. Ainsi, lorsque vous tapez plusieurs, -lllllllllcette variable est définie plusieurs fois, mais cela ne change rien.

Eh bien, cela change une chose. Cette énorme déclaration de cas de commutateur doit s'exécuter plusieurs fois, en raison de plusieurs -lindicateurs. lsa besoin de plus de temps pour terminer avec plusieurs -lindicateurs. Mais cette fois ne mérite pas d'être mentionnée. =)

le chaos
la source
11
Ou pour le dire autrement, les rejeter serait plus de travail pour le programmeur que de les ignorer.
Mark
1
+0,5 pour avoir dit ce que j'allais dire, +0,5 pour être allé à la source.
un CV
@Mark - Pourquoi est-ce plus de travail pour le programmeur?
Ryan Il y a
21

Parce que c'est la bonne chose à faire. Supposons que vous ayez un script faisant quelque chose comme:

ls $LS_OPTIONS -l "$dir"

où il est possible que $LS_OPTIONScontient déjà -l. Il serait contre-intuitif et ennuyeux que cette commande produise une erreur et nécessiterait une logique supplémentaire dans le script pour l'éviter.

-lpeut-être pas le meilleur exemple pour cela, mais j'espère que vous pouvez voir comment le concept s'applique en général. Un bien meilleur exemple est les options du compilateur $CFLAGSqui pourraient dupliquer des options explicites dans une invocation particulière du compilateur.

R .. GitHub ARRÊTEZ D'AIDER LA GLACE
la source
4
La même chose pourrait également se produire si vous aviez défini un alias qui appelle lsavec un ensemble d'options.
kasperd
1
@kasperd: Oui. Bien que l'insertion -lde votre lsalias semble être une mauvaise idée, le même problème est susceptible de se produire avec des options agréables dans un lsalias interactif comme -pou --color=auto.
R .. GitHub STOP STOPINGING ICE
1
Il n'est pas nécessaire d'appeler l'alias ls. llpourrait être un alias pour ls -l, et sur un système avec cet alias, je pourrais taper ll -lart.
kasperd
11

lsn'est pas une bashcommande, mais un exécutable distinct à partir duquel vous lancez bash. Cela dit, ce -ln'est qu'un type d'indicateur booléen qui, s'il est présent, entraîne l' lsutilisation d'un format de style long pour la sortie. La plupart des programmes ignoreront simplement les utilisations multiples ( ls -llc'est la même chose que ls -l -l) de ces indicateurs, bien qu'il y ait quelques exceptions (par exemple, si -vsignifie "verbeux", alors un programme peut interpréter plusieurs utilisations pour signifier "être encore plus verbeux").

chepner
la source
2
Un exemple de -vvvest ssh.
Bernhard
Ou mêmeaptitude moo
Ruslan
8

Les alias de shell seraient assez ennuyeux si des commandes telles lsque ne permettaient pas les options répétées.

Supposons que vous ayez

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

Ensuite, si des indicateurs conflictuels n'étaient pas autorisés, ce serait une erreur de lancer des commandes comme ls --color=neverou ls --color=autoou rm -i.

Par conséquent, ces commandes sont conçues pour permettre aux indicateurs ultérieurs de remplacer les indicateurs précédents.

200_success
la source
Les commutateurs en conflit sont parfois interdits. (Essayez rsync avec les deux --inplaceet --delay-updates, par exemple.) Certains outils prennent simplement ce qui vient en dernier; rm -ifen est probablement un bon exemple. Mais il n'y a pas de conflit dans l' option -l de ls, par conséquent ls -let ls -lln'est pas un problème, et il ne modifie pas l' exécution d'une manière significative. Les ordinateurs sont bons pour la répétition ahurissante.
un CVn