nullglob: когда *.log внезапно превращается в строку
Bash умеет раскрывать glob-шаблоны:
*.log
Но если файлов с таким расширением нет, по умолчанию шаблон может остаться обычной строкой.
Например:
for file in /var/log/*.log; do
echo "$file"
done
Если .log файлов нет, цикл может получить буквально:
/var/log/*.log
Это легко превращается в ошибку в автоматизации.
▪️Включаем nullglob
shopt -s nullglob
Теперь шаблон без совпадений исчезает:
files=(/var/log/*.log)
echo "${#files[@]}"
Если файлов нет: 0
А не 1 с буквальным *.log.
▪️Почему это важно для массивов
Без nullglob:
files=(/tmp/*.tmp)
может создать массив из одного элемента:
/tmp/*.tmp
После:
shopt -s nullglob
получаем действительно пустой массив.
▪️nullglob влияет только на текущий shell
Его можно включить локально внутри функции:
check_logs() {
local old_nullglob
shopt -q nullglob
old_nullglob=$?
shopt -s nullglob
files=(/var/log/*.log)
((${#files[@]})) && printf '%s\n' "${files[@]}"
((old_nullglob == 0)) || shopt -u nullglob
}
Но для простых скриптов обычно достаточно включить настройку в начале.
▪️А если отсутствие файлов должно быть ошибкой?
Тогда существует противоположная настройка:
shopt -s failglob
При отсутствии совпадений Bash выдаст ошибку вместо передачи буквального шаблона дальше.
▪️Почему это важно
Glob кажется простой частью Bash, пока скрипт не запускается на сервере, где ожидаемых файлов просто нет.
nullglob позволяет отличить настоящий список файлов от строки с нераскрытым шаблоном - особенно полезно при работе с массивами, логами и автоматической обработкой каталогов.
BashTex 📱 #bash #linux
Bash умеет раскрывать glob-шаблоны:
*.log
Но если файлов с таким расширением нет, по умолчанию шаблон может остаться обычной строкой.
Например:
for file in /var/log/*.log; do
echo "$file"
done
Если .log файлов нет, цикл может получить буквально:
/var/log/*.log
Это легко превращается в ошибку в автоматизации.
▪️Включаем nullglob
shopt -s nullglob
Теперь шаблон без совпадений исчезает:
files=(/var/log/*.log)
echo "${#files[@]}"
Если файлов нет: 0
А не 1 с буквальным *.log.
▪️Почему это важно для массивов
Без nullglob:
files=(/tmp/*.tmp)
может создать массив из одного элемента:
/tmp/*.tmp
После:
shopt -s nullglob
получаем действительно пустой массив.
▪️nullglob влияет только на текущий shell
Его можно включить локально внутри функции:
check_logs() {
local old_nullglob
shopt -q nullglob
old_nullglob=$?
shopt -s nullglob
files=(/var/log/*.log)
((${#files[@]})) && printf '%s\n' "${files[@]}"
((old_nullglob == 0)) || shopt -u nullglob
}
Но для простых скриптов обычно достаточно включить настройку в начале.
▪️А если отсутствие файлов должно быть ошибкой?
Тогда существует противоположная настройка:
shopt -s failglob
При отсутствии совпадений Bash выдаст ошибку вместо передачи буквального шаблона дальше.
▪️Почему это важно
Glob кажется простой частью Bash, пока скрипт не запускается на сервере, где ожидаемых файлов просто нет.
nullglob позволяет отличить настоящий список файлов от строки с нераскрытым шаблоном - особенно полезно при работе с массивами, логами и автоматической обработкой каталогов.
BashTex 📱 #bash #linux