Файлы с пробелами, табами и спецсимволами - классическая причина мистических багов в bash. Скрипт вроде работает… пока не встретит файл типа:
my file.txt или backup (old).tar.gz➖ Анти-паттерн
for f in $(ls); do
echo "$f"
done
Проблема: bash режет вывод по пробелам и переводам строк. Файл
my file.txt превратится в два разных слова.➕ Правильный способ №1 - glob + кавычки
for f in *; do
echo "$f"
done
Почему это безопаснее: * раскрывается самим shell; каждый элемент цикла - это отдельное имя файла; кавычки сохраняют пробелы.
Если нужен определённый тип:
for f in *.log; do
[[ -e "$f" ]] || continue
echo "$f"
done
[[ -e "$f" ]] защищает, если совпадений нет.➕ Правильный способ №2 - find -print0. Для рекурсивного обхода:
find . -type f -print0 | while IFS= read -r -d '' f; do
echo "$f"
done
Почему это хорошо:
-print0 разделяет файлы нулевым байтом;это безопасно даже для пробелов, табов и спецсимволов;
read -d '' читает до NUL, а не до пробела.▪️ Безопасная передача в xargs
find . -type f -print0 | xargs -0 rm -f
Пара:
-print0 и xargs -0 должны идти вместе.BashTex 📱 #bash #utils