Почему ls принимает дубликаты?

16

Мне любопытно - есть ли разница между ls -lи ls -lllllllllllllllllllllllllllll?

Выходные данные выглядят одинаково, и я не понимаю, почему lsдопускаются дублирующие переключатели. Это стандартная практика среди большинства команд?

Майк Б
источник

Ответы:

17

Краткий ответ :

Потому что он запрограммирован на игнорирование многократного использования флага.

Длинный ответ:

Как вы можете видеть в исходном коде из ls, есть часть с функцией getopt_long()и огромным переключателем случаем:

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     }

Функция getopt_long()читает все параметры, данные программе. В случае, если -lпеременная formatустановлена. Поэтому, когда вы вводите несколько, -lllllllllэта переменная устанавливается несколько раз, но это ничего не меняет.

Ну, это меняет одно. Этот огромный оператор регистра переключателя должен выполняться несколько раз из-за множества -lфлагов. lsтребуется больше времени для дополнения несколькими -lфлагами. Но это время не стоит упоминать. знак равно

хаос
источник
11
Или, другими словами, отказ от них был бы для программиста большим трудом, чем их игнорирование.
Марк
1
+0,5 за то, что я собирался сказать, +0,5 за то, что я пошел к источнику.
CVn
@Mark - Почему это больше работает для программиста?
Райан
@Ryan, отклонение дополнительной опции «l» требует отслеживания количества увиденных и вывода сообщения об ошибке, если их слишком много. Игнорирование дополнительных опций «l» просто требует установки стиля форматирования в «long_format» каждый раз, когда «l» просматривается.
Марк
21

Потому что это правильно. Предположим, у вас есть скрипт, который делает что-то вроде:

ls $LS_OPTIONS -l "$dir"

где это возможно, что $LS_OPTIONSуже содержит -l. Было бы нелогично и раздражающе для этой команды выдавать ошибку, и для ее устранения потребовалась бы дополнительная логика в сценарии.

-lВозможно, это не лучший пример для этого, но, надеюсь, вы увидите, как эта концепция применяется в целом. Гораздо лучший пример - параметры компилятора, $CFLAGSкоторые могут дублировать явные параметры в конкретном вызове компилятора.

R .. GitHub ОСТАНОВИТЬ, ПОМОГАЯ ЛЕД
источник
4
То же самое может произойти, если вы определили псевдоним, который вызывается lsс некоторым набором опций.
Касперд
1
@kasperd: да. Хотя ввод -lв вашем lsпсевдониме кажется плохой идеей, и тот же вопрос, скорее всего, возникает варианты, которые хороши в интерактивном lsпсевдониме , как -pили --color=auto.
R .. GitHub ОСТАНОВИТЬСЯ, ПОМОГАЯ ЛЬДУ
1
Псевдоним не должен называться ls. llможет быть псевдоним для ls -l, и в системе с таким псевдонимом, я мог бы напечатать ll -lart.
Касперд
11

lsэто не bashкоманда, а отдельный исполняемый файл, из которого вы запускаете bash. Тем не менее, -lэто просто тип логического флага, который, если присутствует, вызывает lsиспользование формата длинного стиля для вывода. Большинство программ просто игнорируют многократное использование ( ls -llто же самое, что и ls -l -l) таких флагов, хотя есть некоторые исключения (например, если -vозначает «многословный», то программа может интерпретировать множественное использование как «быть еще более многословным»).

chepner
источник
2
Примером -vvvявляется ssh.
Бернхард
Или дажеaptitude moo
Руслан
8

Псевдонимы оболочки были бы довольно раздражающими, если бы команды вроде lsне позволяли повторять опции.

Предположим, вы имели

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

Тогда, если конфликтующие флаги не были разрешены, было бы ошибкой выдавать команды вроде ls --color=neverили ls --color=autoили rm -i.

Следовательно, эти команды предназначены для того, чтобы более поздние флаги перекрывали более ранние.

200_success
источник
Конфликтующие переключатели иногда запрещены. (Попробуйте rsync с обоими --inplaceи --delay-updates, например.) Некоторые инструменты просто берут то, что последним; rm -ifВероятно, хороший пример там. Но в параметре ls -l конфликта нет, следовательно, ls -lи ls -llэто не проблема, и это никак не влияет на выполнение. Компьютеры хороши в умопомрачительном повторении.
CVN