A resposta é "Provavelmente sim, mas depende do tipo e do tempo do sistema de arquivos".
Nenhum desses três exemplos substituirá os blocos de dados físicos do arquivo antigo ou do arquivo existente, exceto por acaso.
mv new_file old_file
. Isso desvinculará o arquivo antigo. Se houver links físicos adicionais para old_file, os blocos permanecerão inalterados nos links restantes. Caso contrário, os blocos geralmente (dependendo do tipo de sistema de arquivos) serão colocados em uma lista livre. Então, se for mv
necessário copiar (ao contrário de apenas mover as entradas do diretório), novos blocos serão alocados como mv
gravações.
Esses blocos recém-alocados podem ou não ser os mesmos que foram liberados . Em sistemas de arquivos como o UFS , os blocos são alocados, se possível, do mesmo grupo de cilindros que o diretório em que o arquivo foi criado. Portanto, há uma chance de desvincular um arquivo de um diretório e criar um arquivo nesse mesmo diretório ( e sobrescreva) alguns dos mesmos blocos que foram liberados. É por isso que o conselho padrão para as pessoas que removerem acidentalmente um arquivo é não gravar novos dados nos arquivos em sua árvore de diretórios (e de preferência não em todo o sistema de arquivos) até que alguém possa tentar a recuperação do arquivo.
cp new_file old_file
fará o seguinte (você pode usar strace
para ver as chamadas do sistema):
open ("old_file", O_WRONLY | O_TRUNC) = 4
O sinalizador O_TRUNC fará com que todos os blocos de dados sejam liberados, assim como mv
acima. E, como acima, eles geralmente serão adicionados a uma lista gratuita e podem ou não ser reutilizados pelas gravações subsequentes feitas pelo cp
comando.
vi existing_file
. Se vi
for realmente vim
, o :x
comando faz o seguinte:
desvincular ("arquivo_existente ~") = -1 ENOENT (arquivo ou diretório inexistente)
renomear ("arquivo_existente", "arquivo_existente ~") = 0
open ("arquivo_existente", O_WRONLY | O_CREAT | O_TRUNC, 0664) = 3
Portanto, ele nem remove os dados antigos; os dados são preservados em um arquivo de backup.
No FreeBSD, vi
does open("existing_file",O_WRONLY|O_CREAT|O_TRUNC, 0664)
, que terá a mesma semântica que cp
acima.
Você pode recuperar alguns ou todos os dados sem programas especiais; tudo que você precisa é grep
e dd
, e acesso ao dispositivo bruto.
Para arquivos de texto pequenos, o grep
comando único na resposta de @Steven D na pergunta que você vinculou é a maneira mais fácil:
grep -i -a -B100 -A100 'text in the deleted file' /dev/sda1
Mas para arquivos maiores que podem estar em vários blocos não contíguos, faço o seguinte:
grep -a -b "text in the deleted file" /dev/sda1
13813610612:this is some text in the deleted file
que fornecerá o deslocamento em bytes da linha correspondente. Siga isso com uma série de dd
comandos, começando com
dd if=/dev/sda1 count=1 skip=$(expr 13813610612 / 512)
Você também gostaria de ler alguns blocos antes e depois desse bloco. No UFS, os blocos de arquivos geralmente têm 8 KB e geralmente são alocados de maneira bastante contígua, sendo os blocos de um único arquivo intercalados alternadamente com blocos de 8 KB de outros arquivos ou espaço livre. A cauda de um arquivo no UFS é de até 7 fragmentos de 1 KB, que podem ou não ser contíguos.
Obviamente, em sistemas de arquivos que compactam ou criptografam dados, a recuperação pode não ser tão simples.
Na verdade, existem muito poucos utilitários no Unix que sobrescrevem os blocos de dados de um arquivo existente. Um que vem à mente é dd conv=notrunc
. Outro é shred
.