5

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?

Ole Tange
  • 31,768
  • 5
  • 86
  • 104

2 Answers2

3

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.

zdim
  • 64,580
  • 5
  • 52
  • 81
0

These answers say: 'No, not in general, and definitely not on all Unices':

Relinking an anonymous (unlinked but open) file

https://serverfault.com/questions/168909/relinking-a-deleted-file

Copying the content from the open filehandle may work.

Community
  • 1
  • 1
Ole Tange
  • 31,768
  • 5
  • 86
  • 104
  • I completely agree, there is no facility for this and no procedure that works _in general_. I am curious whether I am missing something, why do you say "_Copying the content from the open filehandle **may** work._" (emphasis mine)? What I posted just works (or -- how can it not?), as long as the file is opened `rw`. (It doesn't restore the original link, of course.) – zdim Sep 13 '16 at 07:52
  • Copying content does not work if the whole reason for the relinking is to avoid re-reading the file (which it is in my case). – Ole Tange Sep 13 '16 at 12:34
  • Ah, OK. I didn't realize that that was the purpose. – zdim Sep 13 '16 at 18:34