failglob - почему Bash должен падать при нераскрывшемся glob
Обычно Bash спокойно оставляет glob как есть, если совпадений нет:
rm /var/log/app/*.old
Если .old-файлов нет, команда фактически получит:
rm: cannot remove '/var/log/app/*.old': No such file or directory
Но в автоматизации это может быть проблемой: скрипт продолжит выполнение, хотя вы рассчитывали, что glob что-то нашёл.
▪️failglob меняет поведение
shopt -s failglob
files=(/var/log/app/*.old)
Если совпадений нет, Bash сам выдаст ошибку:
bash: no match: /var/log/app/*.old
То есть проблема обнаруживается на этапе раскрытия glob, ещё до запуска команды.
▪️Особенно полезно в скриптах:
#!/usr/bin/env bash
set -e
shopt -s failglob
for file in /backup/*.tar.gz; do
process "$file"
done
Без failglob цикл может получить буквально строку /backup/*.tar.gz.
С failglob скрипт сразу сигнализирует, что ожидаемых файлов нет.
▪️Но есть нюанс
failglob не всегда нужен. Если отсутствие файлов - нормальная ситуация, лучше использовать nullglob:
shopt -s nullglob
files=(/backup/*.tar.gz)
for file in "${files[@]}"; do
process "$file"
done
Тогда при отсутствии совпадений массив просто будет пустым.
Итого получается:
failglob → отсутствие совпадения считается ошибкой. nullglob → отсутствие совпадения превращается в пустой список.
Для критичных автоматизаций failglob помогает не пропустить логическую ошибку, замаскированную обычным поведением Bash.
BashTex 📱 #bash #linux
Обычно Bash спокойно оставляет glob как есть, если совпадений нет:
rm /var/log/app/*.old
Если .old-файлов нет, команда фактически получит:
rm: cannot remove '/var/log/app/*.old': No such file or directory
Но в автоматизации это может быть проблемой: скрипт продолжит выполнение, хотя вы рассчитывали, что glob что-то нашёл.
▪️failglob меняет поведение
shopt -s failglob
files=(/var/log/app/*.old)
Если совпадений нет, Bash сам выдаст ошибку:
bash: no match: /var/log/app/*.old
То есть проблема обнаруживается на этапе раскрытия glob, ещё до запуска команды.
▪️Особенно полезно в скриптах:
#!/usr/bin/env bash
set -e
shopt -s failglob
for file in /backup/*.tar.gz; do
process "$file"
done
Без failglob цикл может получить буквально строку /backup/*.tar.gz.
С failglob скрипт сразу сигнализирует, что ожидаемых файлов нет.
▪️Но есть нюанс
failglob не всегда нужен. Если отсутствие файлов - нормальная ситуация, лучше использовать nullglob:
shopt -s nullglob
files=(/backup/*.tar.gz)
for file in "${files[@]}"; do
process "$file"
done
Тогда при отсутствии совпадений массив просто будет пустым.
Итого получается:
failglob → отсутствие совпадения считается ошибкой. nullglob → отсутствие совпадения превращается в пустой список.
Для критичных автоматизаций failglob помогает не пропустить логическую ошибку, замаскированную обычным поведением Bash.
BashTex 📱 #bash #linux