Você pode escrever um script de wrapper que extrai os arquivos para um local temporário e os move apenas para o destino final quando eles são concluídos. Algo como
tempdir="incomplete/"
mkdir -p "$tempdir"
zipinfo -1 compressed.zip | while read f ; do
test -f "$f" && continue # skip anything extracted by a previous attempt
printf "extracting %s..." "$f"
unzip -p compressed.zip "$f" > "$tempdir/$f"
printf "done!\n"
mv "$tempdir/$f" "$f"
done
rm -r "$tempdir"
Se isso for interrompido, você ainda terá um arquivo parcial, mas ao executá-lo novamente, ele ignorará os arquivos completos (no local correto) e substituirá imediatamente o parcial (no diretório temporário). Quando finalmente chegar ao final do arquivo, ele removerá completamente o diretório temporário.
Existem alguns limites para o meu script de exemplo. Ele assume que o zip não contém uma estrutura de diretório própria e usa o diretório temporário incomplete/
dentro da pasta de trabalho. Se isso é inaceitável, você teria que
- use outro valor para
tempdir
, que está em algum lugar no mesmo sistema de arquivos (para permitir atômicomv
) e é garantido que não será usado por nenhum outro processo, e - adicione uma etapa
mkdir
adicional, dentro do loop, para reconstruir a estrutura de diretório extraída
Veja também Mv atômico no meu fs?