Есть старый неприятный момент в shell: если читаешь файл и тут же пишешь результат обратно в него же через
>, можно случайно получить пустой файл.Например:
grep -v DEBUG app.log > app.log
На первый взгляд выглядит нормально. На практике — нет.
Shell откроет app.log на запись сразу, ещё до того, как
grep дочитает его до конца. В итоге файл можно просто обнулить.В таких случаях выручает
sponge из moreutils.Он работает просто: сначала полностью читает входной поток, и только потом записывает результат в файл.
То же самое, но безопасно:
grep -v DEBUG app.log | sponge app.log
Несколько примеров, где это реально удобно.
Заменить текст в конфиге:
sed 's/localhost/db.internal/' config.yml | sponge config.yml
Убрать пустые строки:
grep -v '^$' file.txt | sponge file.txt
Отсортировать файл:
sort file.txt | sponge file.txt
Отформатировать JSON:
jq '.' data.json | sponge data.json
Из нюансов:
sponge сначала забирает весь поток целиком, а уже потом пишет в файл. Для обычных задач это вообще не проблема, но на очень больших файлах про это лучше помнить.🔥 Если коротко: когда нужно безопасно перезаписать файл результатом команды,
sponge делает именно то, что ожидаешь.➡️ DevOps Ready | #практика