Ниже приведен быстрый и грязный скрипт sh предназначенный для работы в качестве фильтра (между tar и split в вашем случае). Он был построен в Ubuntu и, возможно, потребует некоторых настроек для других систем (например, я не уверен, является ли column -t | cut -d " " -f 7 правильным способом для анализа df независимо от ОС). Требуется /proc .
Сохраните его как ensuredf куда указывает ваша $PATH , сделайте исполняемый файл (chmod -x ensuredf) и используйте его так:
… | ensuredf path requirement | …
где
path - это каталог, который вы хотите отслеживать;
requirement - желаемое свободное пространство (df -B должен это понимать);
Пример:
… | ensuredf /mnt/foo/data/ 2G | …
Идея состоит в том, чтобы позволить фоновой cat передавать данные из stdin (сценария) в stdout но немедленно приостанавливать их. Затем вызовите df для заданного path , проанализируйте его вывод и проверьте, есть ли больше места, чем requirement . Если это так, cat возобновляется, в противном случае она приостанавливается. Это цикл с жестко заданным интервалом в 1 секунду, пока существует запись /proc для этой cat .
Другие заметки:
- некоторые файловые системы (особенно BTRFS) производят вывод
df не так точно, как хотелось бы;
- если ваш
tar очень быстрый, а требуемое пространство очень мало, интервал в 1 секунду может быть слишком длинным;
- но даже если интервал был нулевым, когда свободное пространство станет меньше
requirement будет некоторая задержка, прежде чем cat будет поставлена на паузу;
- если по какой-то причине сценарий переднего плана задерживается и фоновая
cat работает хорошо, диск все равно может заполниться.
Это означает, что вы должны установить свои requirement с надлежащим запасом прочности. Используйте этот код в качестве примера и приспособьтесь к вашим потребностям. Мне удалось написать более безопасный сценарий, который продолжает вызывать передний план dd для передачи фрагмента данных, если и только если достаточно дискового пространства, но эти несколько процессов dd были намного медленнее, чем один cat .
#!/bin/sh
[ $# -eq 2 ] || { printf '%s\n' "usage: $0 path requirement" >&2 ; exit 1;}
pth="$1"
rqrmnt="$2"
intrvl=1
</proc/$$/fd/0 cat >/proc/$$/fd/1 &
kill -s STOP $!
while [ -d /proc/$! ] ; do
if [ $(df -P -B "$rqrmnt" "$pth" | tail -n 1 | column -t | cut -d " " -f 7) -ge 2 ]
then kill -s CONT $!
else kill -s STOP $!
fi
sleep "$intrvl"
done