Файловая система должна иметь определенный максимальный размер. Но поскольку файловая система -как -файл может быть разреженной , этот размер может быть произвольным числом, которое не имеет большого отношения к тому, сколько места занимает файловая система -как -. файл занимает базовую файловую систему.
Если вы можете согласиться с установкой произвольного ограничения максимального размера (, которое может быть намного больше, чем фактический размер базовой файловой системы )для файловой системы -как -файла, вы можете создать разреженный файл и файловая система на нем прямо сейчас:
/tmp# df -h.
Filesystem Size Used Avail Use% Mounted on
20G 16G 3.0G 84% /
/tmp# dd if=/dev/null bs=1 seek=1024000000000 of=testdummy
0+0 records in
0+0 records out
0 bytes copied, 0.000159622 s, 0.0 kB/s
/tmp# ll testdummy
-rw-r--r-- 1 root root 1024000000000 Feb 19 08:24 testdummy
/tmp# ll -h testdummy
-rw-r--r-- 1 root root 954G Feb 19 08:24 testdummy
Здесь я создал файл, который намного больше, чем файловая система, в которой он хранится...
/tmp# du -k testdummy
0 testdummy
...но пока он вообще не занимает места на диске (за исключением индексного дескриптора и, возможно, некоторых других метаданных ).
Было бы вполне возможно losetup
создать на нем файловую систему и начать ее использовать. Каждая операция записи, которая фактически записывает данные в файл, приведет к увеличению требований к пространству для файла. Другими словами, в то время как размер файла, указанный в ls -l
, все время будет оставаться таким произвольным огромным числом, фактическое пространство, занимаемое файлом на диске, как сообщается в du
, будет расти.
И если вы монтируете файловую систему -как файл -с параметром монтирования discard
, сжатие также может работать автоматически:
/tmp# losetup /dev/loop0 testdummy
/tmp# mkfs.ext4 /dev/loop0
/tmp# mount -o discard /dev/loop0 /mnt
/tmp# du -k testdummy
1063940 testdummy
/tmp# df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/loop0 938G 77M 890G 1% /mnt
/tmp# cp /boot/initrd.img /mnt
/tmp# du -k testdummy
1093732 testdummy
/tmp# rm /mnt/initrd.img
/tmp# du -k testdummy
1063944 testdummy
Для автоматического сжатия требуется:
1. )что тип файловой системы файловой системы -как -файл поддерживает discard
параметр монтирования (, чтобы драйвер файловой системы мог сообщить базовой системе, какие блоки могут быть освобождены)
2. )и что тип файловой системы нижележащей файловой системы поддерживает "перфорирование отверстий", т.е.системный вызов fallocate(2)
с опцией FALLOC_FL_PUNCH_HOLE
(, чтобы базовой файловой системе можно было приказать пометить некоторые из ранее -выделенных блоков файловой системы -как файл -как разреженные блоки)
3. )и что вы используете версию ядра 3.2 или более позднюю, так что поддержка петлевых устройств имеет для этого необходимую инфраструктуру.
https://outflux.net/blog/archives/2012/02/15/discard-hole-punching-and-trim/
Если вас устраивает менее быстрое сжатие, вы можете просто периодически запускать fstrim
в файловой системе -как файл -вместо использования опции монтирования discard
. Если базовая файловая система очень загружена, отказ от немедленного сжатия может помочь свести к минимуму фрагментацию базовой файловой системы.
Проблема с этим подходом заключается в том, что если базовая файловая система переполняется, это не будет корректно обрабатываться. Если в базовой файловой системе больше нет места, файловая система -как файл -начнет получать ошибки при попытке заменить разреженные «дыры» фактическими данными, даже если файловая система -как файл -будет казаться, что осталась неиспользованная емкость.
Проблема заключается в цитировании -и не относится ни к zsh, ни к zmv
В вашем распоряжении
ssh me@myserver "cd /Users/me/mypath; autoload zmv; zmv '(xxx_)(*)' 'yyy_$2'"
«слабые» внешние двойные кавычки не препятствуют тому, чтобы $2
расширялся как (предположительно пустой )позиционный параметр $2
локальной оболочкой -, так что удаленная оболочка видит
cd /Users/me/mypath; autoload zmv; zmv '(xxx_)(*)' 'yyy_'
Если (xxx_)(*)
соответствует двум файлам, то zmv пытается переименовать их оба в yyy_
с результирующей ошибкойboth map to yyy_
Версия с подстановочными знаками в замене (, активируемая переключателем -W
), не страдает от той же проблемы, поскольку подстановочные знаки (оболочки )не раскрываются даже в двойных кавычках.
Самый простой способ решить эту проблему — добавить еще один уровень цитирования, чтобы $2
беспрепятственно передавался в удаленную оболочку:
ssh me@myserver "cd /Users/me/mypath && autoload zmv && zmv '(xxx_)(*)' 'yyy_\$2'"
Здесь также используется &&
вместо ;
, поскольку вы не хотите, чтобы zmv
запускался в случае сбоя cd
, так как в противном случае вы в конечном итоге переименовали бы файлы в домашнем каталоге me
на myserver
. ] вместо.
Для более общего обсуждения проблем, связанных с цитированием и SSH, включая альтернативный обходной путь с использованием документа здесь -, см., например, соответствующий вопрос