A maioria abaixo é um script rápido e sujo sh desenvolvido para funcionar como um filtro (entre tar e split no seu caso). Ele foi criado no Ubuntu e pode precisar de alguns ajustes para outros sistemas (por exemplo, não sei se column -t | cut -d " " -f 7 é o caminho certo para analisar df independentemente do sistema operacional). Requer /proc .
Salve como ensuredf para onde $PATH aponta, torne executável ( chmod -x ensuredf ) e use assim:
… | ensuredf path requirement | …
onde
-
pathé o diretório que você deseja monitorar; -
requirementé o espaço livre desejado (df -Bdeve entender isso);
Exemplo:
… | ensuredf /mnt/foo/data/ 2G | …
A ideia é permitir que o plano de fundo cat passe dados de stdin (do script) para stdout , mas pause imediatamente. Em seguida, invoque df para um determinado path , analise sua saída e verifique se há mais espaço que requirement . Em caso afirmativo, cat é retomado, caso contrário, ele é pausado. Isso faz um loop com um intervalo codificado de 1 segundo, contanto que /proc entrada para esse cat exista.
Outras notas:
- alguns sistemas de arquivos (especialmente BTRFS) tornam a saída
dfnão tão exata quanto você gostaria; - se o seu
tarfor muito rápido e o espaço necessário for muito baixo, o intervalo de 1 segundo poderá ser muito longo; - mas, mesmo que o intervalo seja zero, quando o espaço livre ficar abaixo do
requirement, haverá algum atraso antes que ocatseja pausado; - se por algum motivo o script de primeiro plano for atrasado e o plano de fundo
catfuncionar bem, o disco poderá ficar cheio de qualquer maneira.
Isso significa que você deve definir seu requirement com a margem de segurança adequada. Use este código como um exemplo e ajuste suas necessidades. Consegui escrever um script mais seguro que invoca o primeiro plano dd para passar um pedaço de dados se e somente se houver espaço em disco suficiente, mas esses vários processos dd eram muito mais lentos que um único 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