unlink
does not delete a file, if it is open; it just removes the name and the link to the name. Can unlink
be undone?
open(my $fh, ">", undef) || die;
print $fh "foo";
# This does not work
link($fh,"/tmp/bar") || die;
Can an open file handle to an unlinked file be linked to a file?
If feasible, you can change the open mode ('>'
) to be read/write instead. Then, when you need to recover the file you can use the filehandle to print it out to a newly opened file, even with the same name if needed.
open my $fh, '+>', $file;
say $fh "line 1";
unlink $file;
say $fh "more lines";
seek $fh, 0, 0;
open my $fh_rec, '>', $file or die "Can't open $file (again): $!";
print $fh_rec $_ while <$fh>;
This isn't exactly what is asked but it recovers the file content and access
to it. Further prints to $fh
would leave the new $file
out of sync, so this can be done when writing's done (to restore the file) or to switch the printing to $fh_rec
(then also close $fh
).
Another way to recover a file is by using the OS, if it uses /proc
and exposes file handles. Then the data can be copied from /proc/PID/fd/N
. To identify N
one can scan all links that are in fd/
(a few) with ls -l
, since the deleted file should have (deleted)
after its name.
Also, lsof -p PID
lists all open file descriptors for the given process. The ones for deleted files have (deleted)
with them. (The lsof +L1 -p PID
outputs only deleted entries, still quite a few.) From this output we can read off that file descriptor and then copy the data from /proc/PID/fd/N
. This way we also get the inode number, which can also be used to recover the file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With