Frequentemente, executamos um executável que precisa gravar / ler alguns arquivos temporários. Geralmente criamos um diretório temporário, executamos o executável lá e excluímos o diretório quando o script é concluído.
Eu quero excluir o diretório mesmo que o executável seja morto. Eu tentei envolvê-lo em:
#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary
Quando my_binary
morrer, o último processo em que o kernel excluirá o diretório, pois o script é o último processo que o mantém inode
; mas não consigo criar nenhum arquivo no diretório excluído.
#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt
saídas touch: file.txt: No such file or directory
O melhor que pude descobrir é excluir o diretório temp quando o processo morrer, captando os sinais mais comuns e executar um processo de limpeza com o cron:
#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary
Existe alguma maneira simples de criar um diretório realmente temporário que é excluído automaticamente quando o binário atual morre, não importa o quê?
cleanup
pode ser executada antes que o mktemp esteja pronto. Você pode quererunset dir
antes de montar a armadilha.Respostas:
Seu último exemplo é o mais seguro contra falhas.
Isso será executado enquanto o próprio shell ainda estiver funcional. Basicamente, o SIGKILL é a única coisa com a qual não vai lidar, já que o shell é terminado à força.
(talvez o SIGSEGV também não tenha tentado, mas pode ser pego)
Se você não deixar o shell limpar sozinho, a única outra alternativa possível é fazer com que o kernel faça isso. Normalmente, isso não é um recurso do kernel, mas há um truque que você pode fazer, mas ele tem seus próprios problemas:
Basicamente, você cria uma montagem tmpfs e desmonta-a lentamente. Depois que o script estiver pronto, ele será removido.
A desvantagem, além de ser excessivamente complexa, é que, se o script morrer por qualquer motivo antes da desmontagem, você não terá uma montaria por aí.
Isso também usa tmpfs, que consumirá memória. Mas você pode tornar o processo mais complexo e usar um sistema de arquivos em loop e remover o arquivo que o suporta depois de montado.
Em última análise, o
trap
melhor é no que diz respeito à simplicidade e segurança, e, a menos que seu script seja regularmente SIGKILLed, eu continuaria com ele.fonte
mktemp
ou depois dela? Eu acho que se a armadilha for colocada logo antes damktemp
, mesmo que o sinal de saída seja recebido após a armadilha e antes damktemp
, tudo o que aconteceria é que umrm -rf
comando seria executado com um argumento vazio, sem realizar nada. Mas se a armadilha estivesse atrás damktemp
, poderia haver uma pequena janela de chance de que o diretório temporário fosse deixado. Ou estou completamente fora da base?Você pode usar a espera incorporada para aguardar a conclusão de um trabalho em segundo plano:
fonte
blah; rm -rf $DIR
, certo? Ele tem o problema de vazar $ DIR se o script for morto.