Я ожидал не получить никакого вывода.
Если бы nullglobони использовались по умолчанию, многие команды вели бы себя совершенно неожиданно, потому что, как правило (к сожалению), команды обрабатывают случай нулевых аргументов имени файла качественно иным образом, чем один или несколько аргументов имени файла.
Предположим, что вы включили nullglob( shopt -s nullglob), и вы находитесь в каталоге, где не найдено ни одного файла *.txt. Тогда *.txtдействительно расширится до нуля - не пустое поле, а вообще никаких полей - как вы и ожидали. Но это будет иметь следующие результаты:
ls *.txtбудет перечислять все файлы в текущем каталоге (кроме скрытых файлов), потому что это то, что lsпроисходит, когда вы не передаете ему аргументы имени файла.
cat *.txtбудет читать со стандартного ввода , потому что, когда catнет аргументов имени файла, это как если бы вы работали cat -. Если он работает в интерактивном режиме, он сидит в ожидании ввода. Многие команды ведут себя таким образом.
cp *.txt dest/потерпит неудачу с ошибкой cp: missing destination file operand after 'dest/'. Это не катастрофа, но это сбивает с толку и весьма отличается от молчаливого успеха, который, вероятно, желателен.
file *.txtи различные другие программы, не имеющие специального поведения для случая нулевых аргументов имени файла, все равно будут с ошибкой или сообщением об использовании, если ни одна из них не будет передана.
- Даже случаи, которые интуитивно чувствуют, что они должны работать часто, не будут.
printf 'Got file: "%s"\n' *.txtбудет печатать Got file: ""вместо ничего.
- Случайное отказ процитировать вхождения
*, ?и [что не предполагается расширить оболочку бы чаще производить очевидно неправильные результаты, но таким образом , что может быть трудно понять. Например, если имена файлов в текущем каталоге не начинаются gedit, то apt list gedit*(где это apt list 'gedit*'было задумано) станет просто apt listи перечислит все доступные пакеты.
Так что хорошо, что вы не получаете такое поведение, не запрашивая его. Вероятно, наиболее распространенной практической ситуацией, которая на самом деле упрощается, nullglobявляется for f in *.txt. Смотрите также этот вопрос (с которым связался ответ Сергея Колодяжного ).
Сложнее ответить на вопрос, почему failglob- если ошибка расширения, связанная с тем, что глобус не соответствует ни одному файлу, - не используется по умолчанию в bash. Я считаю, что ответ Сергея Колодяжного фиксирует причину этого, даже не обращаясь к нему напрямую. Сохранение нерасширяющихся глобусов без возникновения ошибки расширения является (возможно, к сожалению) стандартизированным поведением, а также традиционным и, следовательно, ожидаемым поведением. Хотя bash не пытается быть полностью POSIX-совместимым, если он не вызывается с именем shили не передается --posixопция, многие из его вариантов разработки, даже когда не в режиме POSIX, следуют непосредственно за POSIX. Им пришлось выбрать какое-то поведение, и есть недостатки, связанные с несоответствием ожиданиям пользователей.
Я думаю, что это наименее исторически влиятельный аспект этого вопроса, поэтому я сохранил его напоследок ... но стоит упомянуть, что в nullglobповедении есть что-то немного странно концептуальное .
nullglobна первый взгляд кажется элегантным, поскольку синтаксически он рассматривает случай совпадения файлов с нулями ничем не иначе, как случай с одним, двумя или любым другим числом. Команды, которые мы запускаем, для которых глобусы расширяются в аргументы, не склонны рассматривать их одинаково, как подробно описано выше. Но синтаксически это, по крайней мере, кажется правильным, и я думаю, что это мотивация для вашего вопроса.
И, тем не менее, есть еще одно, более тонкое несоответствие, которое nullglobне устраняется - оно на самом деле усиливается. Случай с нулевыми символами глобинга («подстановочные знаки») трактуется совершенно иначе, чем случай с одним, двумя или любым другим числом. Например, с помощью shopt -s nullglob, если ab?d?fфайлы не совпадают, они удаляются; если ab?dфайлы не совпадают, они удаляются; но если abне совпадает ни с одним файлом (то есть, если нет файла, имя которого точно ab), он все равно не удаляется. Конечно, это будет катастрофа, если она будет удалена, потому что она может вообще не ссылаться на существующий файл в текущем каталоге; это может даже не ссылаться на файл. Но это все еще устраняет любую надежду на полную последовательность.
Три поведения, которые предоставляет bash - по умолчанию обработка глобусов, которые не соответствуют ни одному из файлов, как если бы они не были глобусами, и передача их нерасширенными, поведение, которое вы ожидали от них (если вы простите этот странный поворот фразы) как означающий все нули файлов, которые соответствуют match ( nullglob), и безопасное поведение, учитывающее их ошибки ( failglob) - все они представляют разные подходы к неоднозначности, присущей оболочке, и не могут знать, предназначено ли какое-либо конкретное слово быть имя файла. Оболочка выполняет свои расширения без знания того, как конкретные команды, которые вы вызываете с ней, будут обрабатывать свои аргументы.
Это один из многих случаев разделения интересов . В системах, дизайн которых соответствует философии Unix, каждая часть предназначена для того, чтобы делать что-то одно и делать это хорошо . Оболочка обрабатывает текст в команды и аргументы и вызывает те команды, большинство из которых являются внешними по отношению к самой оболочке. Это, как правило, намного приятнее и гибче, чем системы, в которых внешние команды сами отвечают за выполнение этих преобразований (как в случае традиционных командных процессоров в DOS и Windows). Но у этого есть свои случайные недостатки.
shopt -s nullglobвыдаст пустые строки для несопоставленных шаблонов иshopt -u nullglob(стандартная настройка) выдаст сам шаблон.