Hala bir işlem tarafından açılmışsa silinen dosya nasıl kurtarılır?


19
$ cat important_file > /dev/null &
[1] 9711
$ rm important_file 
$ killall -STOP cat

[1]+  Stopped                 cat important_file > /tmp/p
$ ls -l /proc/`pidof cat`/fd/
total 0
lrwx------ 1 vi vi 64 May 13 20:32 0 -> /dev/pts/29
l-wx------ 1 vi vi 64 May 13 20:32 1 -> /tmp/p
lrwx------ 1 vi vi 64 May 13 20:32 2 -> /dev/pts/29
lr-x------ 1 vi vi 64 May 13 20:32 3 -> /home/vi/important_file (deleted)

Bunu nasıl kurtarabilirim important_file?

Gibi bir şey denedim

injcode -m dup2 -ofd=3 -ofilename=/tmp/recovered_file -oflags=O_CREAT $PID_OF_CAT

ama hiçbir şey yapmıyor.

Yanıtlar:


11

/ Home NFS ise, / home / vi dosyasında erişebileceğiniz / kopyalayabileceğiniz bir .nfsNNNNNNNNNN dosyası olacaktır. Home yerel bir dosya sistemiyse, aynı işlemi / proc / PID / fd / 3 bağlantısıyla da yapabilmeniz gerekir:

cp /proc/PID/fd/3 /tmp/recovered_file

Dosyayı gerçekten geri almak istiyorsanız, işte konuyla ilgili bir blog yazısı .


1
Tamam, kafam karıştı readlink /proc/13381/fd/3-> "/ home / vi / important_file (silindi)" ve /home/vi/important_file\ \(deleted\)belli ki mevcut değil.
Vi.

22

... belirli bir zamanda kopyalamaktan daha iyidir (ve yalnızca dosyanın içeriğinin o zamanın anlık görüntüsünü toplamak) tail -fbu dosyayı yeni bir dosyaya " " eklemektir:

tail -c +0 -f /proc/PIDofProgram>/fd/# > /new/path/to/file

(kuyruktaki dikkatli programcılar sayesinde, ikili çıktı ile bile çalışacaktır.)

Çalışma zamanı sırasında tail -f, dosyanın kendisi açık kalır ve orijinal program sona erdiğinde diskten temizlenmesini güvenli bir şekilde önler. Böylece, durma tail -forijinal programı sona erdikten sonra hemen - tail'ed kontrol /new/path/to/fileilk olmadığını ise ne istediğini. Öyle değil mi (ya da herhangi başka bir nedenden dolayı tatmin edici değil), yeniden orijinal dosyayı, ancak bu kez kopyalayabilirsiniz sonra buna tüm yazı "Program" tarafından bitmiş ve hala çalışan gelmiştir tail -f's / proc / PIDoftail / fd / dizin.


3
/ Proc / PIDofProgram> / fd / # için bir bağlantı oluşturmaya ne dersiniz?
becko

2
@becko Invalid cross-device link.
Kamil Maciorowski

10

İnode numarasını bulmak için lsof kullanın ve sabit bir bağlantı oluşturmak için debugfs kullanın. Örneğin:

# lsof -p 12345 | grep /var/log/messages
syslogd 12345 root    3w   REG                8,3    3000    987654 /var/log/messages (deleted)
# mount | grep var
/dev/sda2 on /var type ext3 (rw)
# debugfs -w /dev/sda2
debugfs: cd log
debugfs: ln <987654> tmp
debugfs: mi tmp
                      Mode    [0100600] 
                   User ID    [0] 
                  Group ID    [0] 
                      Size    [3181271] 
             Creation time    [1375916400] 
         Modification time    [1375916322] 
               Access time    [1375939901]
             Deletion time    [9601027] 0
                Link count    [0] 1
               Block count    [6232] 
                File flags    [0x0] 
...snip...
debugfs:  q
# mv /var/log/tmp /var/log/messages
# ls -al /var/log/messages
-rw------- 0 root root 3301 Aug  8 10:10 /var/log/messages

Şikayet etmeden önce, şu anda elinizde silinmiş bir dosya olmadığından yukarıdaki transkripti taklit ettim ;-)

kullanırım miSilme süresini ve bağlantı sayısını anlamlı değerlere (sırasıyla 0 ve 1) sıfırlamak için , ancak düzgün çalışmıyor - bağlantı sayısının sıfırda kaldığını görebilirsiniz ls. Bence çekirdek inode verilerini önbelleğe alıyor olabilir. Güvenli tarafta olmak için, hata ayıklamalarını kullandıktan sonra muhtemelen ilk fırsatta fsck yapmalısınız.

Deneyimlerime göre, bağlantıyı geçici bir dosya adı kullanarak oluşturmalı ve ardından uygun ada yeniden adlandırmalısınız. Doğrudan orijinal dosya adına bağlanması dizin bozulmasına neden oluyor gibi görünüyor. YMMV!


Gerçekten düzgün çalışmıyorsa ve sistem hasarına neden oluyorsa neden bunu tam olarak öneriyorsunuz? Bunun sadece bir WiP olduğu ve üretimde gerçekten denenmemesi gerektiği cevabında daha canlı bir sorumluluk reddi almanız gerektiğini düşünüyorum.
cnst

3

Sadece cpdosyayı, yani:

cp /proc/<pid>/fd/<fdno> /new/path/to/file

Tabii ki, dosya hala değiştiriliyorsa, bu yaklaşımla sorun yaşarsınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.