This is a Linux-specific question.
The bash script is:
echo foo > "a.txt"
exec 3<"a.txt"
cat /dev/fd/3
cat /dev/fd/3
cat /dev/fd/3
Output:
foo
foo
foo
All these cat
s display the content of /dev/fd/3
. But /dev/fd/3
is simply a symlink to a.txt
. That explains the behavior but I don't know if it's guaranteed (and if so, by what) that:
When you run
exec 3<"a.txt"
,/dev/fd/3
is always a symlink toa.txt
.Every time you open and read from
/dev/fd/3
, it returns the entire body.
There is an answer to a similar but not entirely same question:
cat </dev/fd/3
is more portably writtencat <&3
. I can't reproduce what you are seeing. Only the firstcat
should output the whole ofa.txt
. In essence, what you have is{ cat; cat; cat; } <"a.txt"
– Kusalananda Dec 10 '19 at 09:51/dev/fd/3
is most definitely not a symlink to anything. – AlexP Dec 10 '19 at 10:01cat <&3
that's true, because the firstcat
moved the file pointer. But if you usecat </dev/fd/3
it starts from beginning every time.ls -l
tells me/dev/fd/3
is a symlink. Maybe it's different on your system? – Cyker Dec 10 '19 at 10:26ls -l
told me. Similar result on other's system: https://unix.stackexchange.com/questions/74454/somethings-special-about-dev-fd-3 – Cyker Dec 10 '19 at 10:28ls
, to be more friendly. It's not a link. The filesystem itself is virtual, so it's not even a real file. – muru Dec 10 '19 at 10:30ls -l
had to find a way to show you what was the corresponding file, and that was the best it could do. It still isn't a symlink of any kind. It's just a name for the file descriptor #3 of process. – AlexP Dec 10 '19 at 10:33a.txt
three times. Unless you're in a shell that explicitly documents that/dev/fd/3
is the same as "filedescriptor 3", there is no connection betweenexec 3<a.txt
andcat /dev/fd/3
– Kusalananda Dec 10 '19 at 10:33/proc
filesystem is virtual. The point is if it is provided as a filesystem then it can be used like a filesystem. So if/dev/fd/3
is shown as a symlink, then it can be used as a symlink. – Cyker Dec 10 '19 at 10:56cat /proc/self/fd/3
instead? What doesls -l /dev/fd /dev/fd/3 /proc/self/fd/3
show on your machine? – Cyker Dec 10 '19 at 10:59/proc
(I'm not on Linux). The/dev/fd/3
is a character special file (just like/dev/tty
), definitely not a symbolic link. – Kusalananda Dec 10 '19 at 11:02/dev/fd/N
->/proc/self/fd/N
->/path/to/the/original/file
will always open the original file it points to from scratch, and this is completely different from OpenBSD, Solaris, etc whereopen("/dev/fd/N", ...)
will act just likedup(N)
, ie will duplicate the fd. – Dec 10 '19 at 11:09