truncate и fallocate
Обрезать или увеличить файл до нужного размера, создать разреженный или заранее выделенный файл
truncate меняет размер файла: лишнее отрезает, недостающее дописывает нулями — но эти нули не занимают места на диске (файл становится разреженным, sparse). fallocate (из util-linux), наоборот, реально выделяет место под файл. Оба работают мгновенно, в отличие от dd. В песочнице — GNU coreutils 9.4 и util-linux.
Синтаксис
truncate -s РАЗМЕР файл…
truncate -r образец файл…
fallocate -l ДЛИНА файл
fallocate [-o СМЕЩЕНИЕ] -l ДЛИНА {-p|-c|-i|-z} файл
fallocate -d файл
Опции truncate
| Опция | Что делает |
|---|---|
-s РАЗМЕР | установить или изменить размер (формы — в таблице ниже) |
-r файл | взять размер у другого файла; вместе с -s +N/-s -N — относительно него |
-c | не создавать отсутствующие файлы (без -c truncate создаёт файл) |
-o | считать РАЗМЕР в блоках ввода-вывода файла, а не в байтах |
Формы размера
| Запись | Что значит | Пример: файл был 5000 байт |
|---|---|---|
N | ровно N | -s 1000 → 1000 |
+N | увеличить на N | -s +1K → 6024 |
-N | уменьшить на N | -s -1000 → 4000 |
'<N' | не больше N (уменьшить, если больше) | -s '<2000' → 2000 |
'>N' | не меньше N (увеличить, если меньше) | -s '>8000' → 8000 |
/N | округлить вниз до кратного N | -s /4K → 4096 |
%N | округлить вверх до кратного N | -s %4K → 8192 |
Единицы: K, M, G, T — степени 1024; KB, MB, GB — степени 1000. < и > бери в кавычки — иначе это перенаправление оболочки.
Опции fallocate
| Опция | Что делает |
|---|---|
-l ДЛИНА | сколько байт выделить (100M, 1G; MiB = M, MB — степени 1000) |
-o СМЕЩЕНИЕ | с какого места файла (по умолчанию 0) |
-n | выделить место, но не менять видимый размер файла (файл должен существовать) |
-p | «пробить дыру»: превратить диапазон в нули без места на диске (подразумевает -n) |
-c | вырезать диапазон, сдвинув остаток файла (ФС должна уметь; смещение и длина кратны блоку) |
-i | вставить пустой диапазон, сдвинув остаток вперёд |
-z | заполнить диапазон нулями с выделением места |
-d | найти блоки из нулей и сделать их «дырами» — сжать файл на месте |
-x | использовать posix_fallocate — работает везде, но медленно (пишет нули) |
-v | подробный вывод |
Разреженный или выделенный
truncate -s 1G f | fallocate -l 1G f | dd if=/dev/zero … count=1024 bs=1M | |
|---|---|---|---|
ls -l (видимый размер) | 1.0G | 1.0G | 1.0G |
du (место на диске) | 0 | 1.0G | 1.0G |
| Скорость | мгновенно | мгновенно | пишет каждый байт |
| Место гарантировано | нет — может кончиться при записи | да | да |
Видимый и реальный размер сравнивают так: ls -lh f; du -h f или du -h --apparent-size f.
Примеры
# очистить файл, не удаляя его (права и владелец сохранятся)
truncate -s 0 app.log
# файл-заглушка на 1 ГиБ без расхода места — для тестов
truncate -s 1G big.img
ls -lh big.img; du -h big.img
# заранее зарезервировать 500 МиБ под данные
fallocate -l 500M data.bin
# своп-файл (место должно быть реально выделено, не sparse)
fallocate -l 1G /swapfile && chmod 600 /swapfile
# оставить первые 100 байт
truncate -s 100 file.txt
# дорастить до размера, кратного 4 КиБ (образы, выравнивание)
truncate -s %4K disk.img
# такой же размер, как у другого файла
truncate -r original.bin copy.bin
# сделать уже записанные нули «дырами» и освободить место
fallocate -d disk.img
Подводные камни
- Обнуление лога, в который пишут без
O_APPEND. Если процесс открыл файл через>(не>>), послеtruncate -s 0он продолжит писать со старого смещения: в начале файла появятся нулевые байты, а размер вернётся к прежнему. Программы, открывшие лог в режиме дозаписи (>>), пишут правильно с нуля. truncateсоздаёт файл, если его нет. Опечатка в имени не даст ошибки — появится новый пустой файл. Защита —-c.- Sparse-файл может «раздуться».
cp --sparse=never, архиваторы без поддержки дыр, передача по сети превращают нули в реальные байты, и место на диске кончается неожиданно. -s '<N'без кавычек — это-sи перенаправление ввода из файлаN.fallocate -n/-pна несуществующем файле — «cannot open … No such file or directory»: эти режимы файл не создают.- Не каждая ФС умеет
fallocate(-c,-iтребуют ext4/xfs). Там, где не умеет, — «Operation not supported»; поможет-x(медленно) илиdd. - Обрезание необратимо. Отрезанные данные пропадают,
truncate -s +Nих не вернёт — допишет нули.