./program
receives the output of echo
as a file, namely the standard stream file /dev/stdin
. Demo:
echo foo | wc -c
echo foo | wc -c /dev/stdin
Outputs:
4
4 /dev/stdin
Note: a stream file is somewhat different from a file stored on a disk. We can access data randomly in a regular file, but not in a streaming file. It's like the difference between a CD player and radio playing a song. On the CD player we can rewind, fast forward, seek, and skip songs. The radio just outputs (or streams) whatever the broadcaster is sending right now.
Where is the stream stored? The OS stores it in a temporary data buffer, the size of which varies between OSes. See How big is the pipe buffer?
On a lower level, the OS uses file descriptors, not filenames. File descriptors are just a stack of numbers, for which each process identifier has its own stack. Linux also allows accessing the /dev/stdin
stream, (which is always file descriptor "0"), that way:
echo foo | wc -c /proc/self/fd/0
Output:
4 /proc/self/fd/0
One more Linux abstraction can be seen with the realpath
util:
realpath /dev/stdin /proc/self/fd/0
Output (on the current terminal on my system):
/dev/pts/2
/dev/pts/2
The letters pts
stand for Pseudo Terminals. That last 2
number will always vary between terminals, so it's not a reliable name, but those numbers can be used for tricks like: How to send output from one terminal to another without making any new pipe or file.