ZMV (ZSH )ZSH )ov ssh ведет себя по-разному между оболочкой и скриптом

Собственно, нечто подобное уже возможно

Файловая система должна иметь определенный максимальный размер. Но поскольку файловая система -как -файл может быть разреженной , этот размер может быть произвольным числом, которое не имеет большого отношения к тому, сколько места занимает файловая система -как -. файл занимает базовую файловую систему.

Если вы можете согласиться с установкой произвольного ограничения максимального размера (, которое может быть намного больше, чем фактический размер базовой файловой системы )для файловой системы -как -файла, вы можете создать разреженный файл и файловая система на нем прямо сейчас:

/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. Если базовая файловая система очень загружена, отказ от немедленного сжатия может помочь свести к минимуму фрагментацию базовой файловой системы.

Проблема с этим подходом заключается в том, что если базовая файловая система переполняется, это не будет корректно обрабатываться. Если в базовой файловой системе больше нет места, файловая система -как файл -начнет получать ошибки при попытке заменить разреженные «дыры» фактическими данными, даже если файловая система -как файл -будет казаться, что осталась неиспользованная емкость.

1
29.06.2020, 01:26
1 ответ

Проблема заключается в цитировании -и не относится ни к 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, включая альтернативный обходной путь с использованием документа здесь -, см., например, соответствующий вопрос

2
18.03.2021, 23:23

Теги

Похожие вопросы