Я очікував, що не отримаю жодного результату.
Якби 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), він все одно не буде видалений. Звичайно, це було б катастрофою, якби його було видалено, тому що воно взагалі може не мати на меті посилання на існуючий файл у поточному каталозі; він може навіть не посилатися на файл. Але це все ж усуває будь-яку надію на повну послідовність.
Три баші поведінки передбачають - за замовчуванням обробляти глобуси, які не відповідають жодному файлу, як ніби вони не були глобусами і передавали їх нерозкритим, поведінку, яку ви очікували від їх обробки (якщо ви помилуєте цей дивний поворот фрази) як означають всі нулі файлів, які відповідають ( nullglob), і безпечну поведінку при розгляді їх помилок ( failglob) - всі представляють різні підходи до неоднозначності, притаманної оболонці, не в змозі знати, чи призначене якесь конкретне слово ім'я файлу. Оболонка виконує свої розширення, не знаючи, як конкретні команди, з якими ви викликаєте, будемо ставитися до їхніх аргументів.
Це один із багатьох випадків розділення проблем . У системах, дизайн яких відповідає філософії Unix, кожна частина має на меті зробити одне і зробити це добре . Оболонка обробляє текст у команди та аргументи та викликає ті команди, більшість з яких є зовнішніми для самої оболонки. Це, як правило, набагато приємніше і універсальніше, ніж системи, де зовнішні команди самі відповідають за виконання цих перетворень (як це стосується традиційних процесорів команд в DOS і Windows). Але це має свої випадкові мінуси.
shopt -s nullglobвийдуть порожні рядки для невідповідних шаблонів іshopt -u nullglob(стандартне налаштування) дасть сам шаблон.