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.