I'm working on some script that being run by rc.local at startup, and I noticed that output redirection works quite strange.
If I write something like echo "foo" >&1, it ends up in syslog, and all is okay.
But when I write echo "foo" >>/dev/stdout, or echo "foo" >>/proc/self/fd/1, I got an error saying that there is no such device or address.
Further investigation revealed that /proc/self/fd/1 was in fact a socket.
Including ls -l /proc/self/fd in rc.local prints the following:
lr-x------. 1 root root 64 Jul 14 05:28 0 -> /dev/null
lrwx------. 1 root root 64 Jul 14 05:28 1 -> socket:[18485]
lrwx------. 1 root root 64 Jul 14 05:28 2 -> socket:[18485]
lr-x------. 1 root root 64 Jul 14 05:28 255 -> /etc/rc.d/rc.local
The described behaviour can be easily reproduced with nc. First, find out which file descriptor binds to socket. You can do it by issuing nc -l -p 25566 -c "ls -l /proc/self/fd" in first terminal and then telnet localhost 25566 in other terminal. In my case it was 5-th descriptor.
Okay. Then, to reproduce the issue, in first terminal:
nc -l -p 25566 -c "echo 'hello' >&5"
in second terminal:
telnet localhost 25566
You shall see "hello" in second terminal output between telnet messages about connection being established and closed.
Now the case with file descriptor pseudo-file from /proc:
first terminal:
nc -l -p 25566 -c "echo 'hello' >/proc/self/fd/5"
second terminal:
telnet localhost 25566
Now second terminal just contains telnet messages about connection established and immediately closed, and first terminal shows an error: sh: /proc/self/fd/5: No such device or address.
Edit: OS is Fedora 23 i686 server
So, the question. What's the difference between >&1 and >/proc/self/fd/1 ? And is there some universal and reliable way to redirect output to some file, which corresponds exactly to current standard output?
Thank you.
Edit 2:
For clarity, exact input/output for Fedora 23 i686 for above case:
Terminal 1 | Terminal 2
$ nc -l -p 25566 -c 'ls -go /proc/self/fd' |
| $ telnet localhost 25566
| Trying ::1...
| Connected to localhost.
| Escape character is '^]'.
| total 0
| lr-x------ 1 64 Jul 14 08:56 0 -> pipe:[19687]
| l-wx------ 1 64 Jul 14 08:56 1 -> pipe:[19688]
| lrwx------ 1 64 Jul 14 08:56 2 -> /dev/tty2
| lr-x------ 1 64 Jul 14 08:56 3 -> pipe:[19687]
| lr-x------ 1 64 Jul 14 08:56 4 -> /proc/1285/fd
| lrwx------ 1 64 Jul 14 08:56 5 -> socket:[19686]
| l-wx------ 1 64 Jul 14 08:56 7 -> /pipe:[19688]
| Connection closed by foreign host.
$ nc -l -p 25566 -c "echo 'hi' >&5" |
| $ telnet localhost 25566
| Trying ::1...
| Connected to localhost.
| Escape character is '^]'.
| hi
| Connection closed by foreign host.
$ nc -l -p 25566 -c "echo 'hi' >/proc/self/fd/5" |
| $ telnet localhost 25566
| Trying ::1...
| Connected to localhost.
sh: /proc/self/fd/5: No such device or address | Escape character is '^]'.
| Connection closed by foreign host.
$ | $
nc -l -p 25566 -c "ls -l /proc/self/fd"I get the socket attached tofd/0andfd/1this is what I expected.