Почему nullglob не является дефолтом?

В большинстве оболочек значение nullglob не является значением по умолчанию. Это означает, например, если вы запустите эту команду

 ls * 

в пустом каталоге он будет расширять * glob до литерала * , а не пустым списком аргументов. Есть способы изменить это поведение, так что * в пустом каталоге вернет пустой список аргументов, что будет казаться более интуитивным.

Итак, есть причина, по которой nullglob отключен по умолчанию? Если да, то в чем причина?

One Solution collect form web for “Почему nullglob не является дефолтом?”

Опция nullglob (которая BTW является изобретением zsh , добавленная только спустя годы в bash ( 2.0 )), не будет идеальной в ряде случаев. И ls – хороший пример:

 ls *.txt 

Или его более правильный эквивалент:

 ls -- *.txt 

С помощью nullglob on будет выполняться ls без аргумента, который обрабатывается как ls -- . (укажите текущий каталог), если файлы не совпадают, что, вероятно, хуже, чем вызов ls с литералом *.txt качестве аргумента.

У вас была бы аналогичная проблема с большинством текстовых утилит:

 grep foo *.txt 

Посмотрел бы foo на stdin, если нет txt файла.

Более разумный дефолт, а один из csh, tcsh, zsh или fish 2.3+ (и ранних Unix-оболочек) – полностью отменить команду, если glob не соответствует.

bash (начиная с версии 3) имеет параметр failglob для этого (интересно этому обсуждению, поскольку вопреки zsh или ksh93 bash не поддерживает локальные области для параметров (хотя это должно измениться в 4.4), этот параметр, когда он включен глобально, прерывает несколько вещей, таких как функции завершения bash).

Обратите внимание, что csh и tcsh немного отличаются от zsh , fish или bash -O failglob в таких случаях, как:

 ls -- *.txt *.html 

Где вам нужно, чтобы все глобы не совпадали для команды, которую нужно отменить. Например, если есть один файл txt и html-файл, это становится:

 ls -- file.txt 

Вы можете получить это поведение с помощью zsh с помощью setopt cshnullglob хотя более разумным способом сделать это в zsh было бы использование glob типа:

 ls -- *.(txt|html) 

В zsh вы также можете применять nullglob по принципу « один глобус» , что намного более разумно, чем изменение глобальной настройки:

 files=(*.txt(N)) 

создаст пустой массив, если нет txt файла вместо отказа от команды с ошибкой (или создания массива с одним литеральным аргументом *.txt с другими оболочками).

Версии fish до 2.3 будут работать как bash -O nullglob но дают предупреждение, когда интерактивны, когда glob не имеет соответствия. Начиная с версии 2.3, он работает как zsh за исключением глобусов, используемых в for , set или count .

Теперь, в примечании к истории, поведение было фактически нарушено оболочкой Bourne. В предыдущих версиях Unix globbing выполнялся с помощью помощника /etc/glob и этот помощник вел себя как csh : он не выполнил команду, если ни один из globs не соответствовал любому файлу и не удалил бы globs без соответствия.

Таким образом, ситуация, в которой мы находимся сегодня, вызвана плохим решением, принятым в оболочке Bourne.

Обратите внимание, что оболочка Bourne (и оболочка C) поставляется с другой новой функцией Unix: средой. Это означало переменное расширение (у его предшественника были только позиционные параметры $1 , $2 …). В оболочке Bourne также была введена подстановка команд.

Еще одно плохое дизайнерское решение оболочки Bourne состояло в том, чтобы выполнить глобальное (и разделение) разворот переменных и подстановку команд (возможно, для обратной совместимости с оболочкой Thompson, где echo $1 все равно будет вызывать /etc/glob если $1 содержит подстановочные знаки (это было больше похоже на расширение макропроцессора, поскольку в расширенном значении снова анализируется как код оболочки)).

Неудачные шары, которые не совпадают, означают, например, что:

 pattern='a.*b' grep $pattern file 

(если в текущем каталоге нет некоторых файлов a.whateverb ). csh (который также выполняет зависание при расширении переменной) не выполняет команду в этом случае (и я бы сказал, что это лучше, чем оставить бездействующую ошибку там, даже если это не так хорошо, как не делать глобусы вообще, как в zsh ).

  • Как найти файлы с определенными расширениями, исключая только имена в текущем каталоге?
  • Odd alias "find. -name '* \! {*} *' -ls "в Unix Power Tools
  • Как я могу найти файл с фиксированной длиной имени, используя ls?
  • Как заставить tar-манипулировать работой с опцией «change directory»
  • SFTP chroot jail / access на основе шаблона
  • Список только обычных файлов (но не каталогов) в текущем каталоге
  • Bash globbing: как выражать "что-то - *. Txt кроме * -foobar.txt" как glob?
  • Начать глобус с шаблоном исключения
  • Bash скрывает скрытые файлы
  • поиск файлов с использованием группового разрешения
  • Настроить баш-глобус
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.