When the target of a symbolic link is deleted, it points to nothing and there's no way to get to the content of the deleted target.
Files in /proc/$PID/fd/
are displayed as symbolic links, but they allow you to get to the deleted target's content, as explained here: Recover Deleted Linux Files With lsof
.
How does that work? Why is it displayed as a symbolic link if it doesn't act as one? Is it the symbolic link implementation of the proc filesystem that keeps a reference to the inode of the file?
Best Answer
If its target is deleted, an entity in
/proc/$PID/fd/
appears as a broken symbolic link when you usels(1)
orfile(1)
, but it indeed acts differently when being opened withopen(2)
.On my Debian 9 I used
strace(1)
to see what happens when I try to read a symlink. The command issudo strace cat "$symlink"
. The relevant line from stderr iseither OK
or
ENOENT
(note: I'm not saying these are all possible outcomes of
open(2)
in general).The results:
I also learnt that when I run
file "$symlink"
, it callslstat(2)
,readlink(2)
andstat(2)
. These are system calls that base on paths, not file descriptors. If the symlink exists (valid or broken),open(2)
is never called to open it or its target.ENOENT
fromstat(2)
indicates the link is broken.My conclusion is: "broken link" is a property derived from the output of some system call(s); but when you open a link from
/proc/$PID/fd/
,open(2)
just knows what to do with it and doesn't care what other tool(s) would yield.Note the entire
/proc
only fakes a "normal" filesystem. Few quirks:inotifywait
).inotifywait
).bash
and wait few minutes. Invokels -l /proc/$$/fd
to see its file descriptors. Probably ctimes will show "this very moment". Yet if you repeat the command every few seconds, you will notice the ctimes never change. (Trivia: at first I though I could answer this question Determine how long a file has been open withstat
and symlinks in/proc/$PID/fd/
but I was wrong; now you know why).No wonder these symlinks you ask about don't behave like regular symlinks in some circumstances. The entire
/proc
was designed to behave somewhat differently. I supposeopen(2)
was deliberately given the ability to take advantage of it.