Знаете ли вы, почему rm *.log не удалит все log-файлы?
Если в каталоге лежат app.log и .debug.log, логика команды rm *.log выглядит, на первый взгляд, очевидно: она должна удалить все файлы с таким суффиксом. Но на самом деле, скрытый файл останется на месте – rm получает уже раскрытый shell-список файлов, а не шаблон, и в этот список скрытые имена не попадают.
mkdir -p demo && cd demo
touch app.log .debug.log
printf "%s\n" *.log
# app.log
rm *.log
ls -a
# .
# ..
# .debug.log
Shell раскрывает *.log до запуска rm: смотрит в текущий каталог, выбирает имена, подходящие под шаблон, и подставляет их в команду. В примере под шаблон подходит app.log, поэтому запускается rm app.log. .debug.log начинается с точки, а такие имена попадают только в шаблоны, где точка написана явно.
Чтобы скрытый файл попал в glob, точку нужно написать явно:
touch app.log .debug.log
printf "%s\n" *.log .*.log
# app.log
# .debug.log
rm *.log .*.log
ls -a
# .
# ..
Но .* как универсальный паттерн для удаления лучше не использовать вслепую: он слишком широкий и цепляет не только нужные файлы. Для конкретной задачи безопаснее писать конкретный суффикс, например .*.log, или сначала посмотреть раскрытие через printf "%s\n" ....
Glob раскрывается до запуска команды. rm *.log удаляет только те пути, которые shell подставил вместо *.log. Скрытые имена начинаются с точки, поэтому для них точка должна быть в шаблоне явно.
Код на салфетке x Кусочки кода
Если в каталоге лежат app.log и .debug.log, логика команды rm *.log выглядит, на первый взгляд, очевидно: она должна удалить все файлы с таким суффиксом. Но на самом деле, скрытый файл останется на месте – rm получает уже раскрытый shell-список файлов, а не шаблон, и в этот список скрытые имена не попадают.
mkdir -p demo && cd demo
touch app.log .debug.log
printf "%s\n" *.log
# app.log
rm *.log
ls -a
# .
# ..
# .debug.log
Shell раскрывает *.log до запуска rm: смотрит в текущий каталог, выбирает имена, подходящие под шаблон, и подставляет их в команду. В примере под шаблон подходит app.log, поэтому запускается rm app.log. .debug.log начинается с точки, а такие имена попадают только в шаблоны, где точка написана явно.
Чтобы скрытый файл попал в glob, точку нужно написать явно:
touch app.log .debug.log
printf "%s\n" *.log .*.log
# app.log
# .debug.log
rm *.log .*.log
ls -a
# .
# ..
Но .* как универсальный паттерн для удаления лучше не использовать вслепую: он слишком широкий и цепляет не только нужные файлы. Для конкретной задачи безопаснее писать конкретный суффикс, например .*.log, или сначала посмотреть раскрытие через printf "%s\n" ....
Glob раскрывается до запуска команды. rm *.log удаляет только те пути, которые shell подставил вместо *.log. Скрытые имена начинаются с точки, поэтому для них точка должна быть в шаблоне явно.
Код на салфетке x Кусочки кода