3

/dev/null is a special Linux file which discards everything is written to itself and which provides EOF when read.

I would like to read /dev/null to obtain and visualize this EOF. If I try:

$ cat /dev/null | hexdump

it doesn't work. The prompt returns with no output. EOF doesn't even have an ASCII code, so maybe this is the reason.

  1. Can EOF still be considered a character?

  2. Is there a way in bash to detect and print EOF, when provided in the stdin?

Something like:

$ cat /dev/null | some_tool
EOF

I'm using GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu) on Ubuntu 20.04.3, but I hope that the solution, if any, is not related to these specific versions.


This is not a homework, but just a way to learn more about EOF.

3
  • 1
  • You mentioned "clarifying your problem" in the comments, but I can't see what the actual problem here would be. Is detecting the EOF (from /dev/null or any other source) actually important for you for trying to complete some concrete task? And what is that task?
    – ilkkachu
    Sep 21 at 18:07
  • 1
    @ilkkachu It is not for a specific task or homework. I just never dealt so much with EOF and wanted to make some practice about it.
    – BowPark
    Sep 21 at 18:16
7

Despite there being a series of "End of {something}" characters defined in the original ASCII control character set, EOF is not a character. EOF is a situation that can be detected because nothing more can be read from the input stream.

For example, this loop will continue until there is nothing more to read (i.e. EOF has been reached)

while IFS= read -r line; do echo "Read: >> $line <<"; done; echo 'No more'

Or more efficiently, avoiding a shell loop entirely

sed 's/.*/Read: >> & <</'; echo 'No more'

The default setting for a terminal is that Ctrl D is used to indicate EOF. It doesn't send a character, though; it tells the terminal tty driver that there's nothing more to read (see stty -a and look for eof). The shell or other application connected to the terminal reads nothing more so knows it's hit EOF.

3
  • Thank you. Maybe you forgot an = sign after IFS in the first version. I edited the question to clarify the problem I deal with.
    – BowPark
    Sep 21 at 17:24
  • Ok, IIUC it addresses (2) this way: there is no "direct method" to detect and print EOF, but it's possible to take some actions when it occurs, as you do in your scripts, so it can be detected in an indirect way.
    – BowPark
    Sep 21 at 18:19
  • The method for detecting an end of file is that there is nothing more to read
    – roaima
    Sep 21 at 21:24
4

What you get from /dev/null is just that the read() system call returns successfully with zero bytes read. That's the same as happens when trying to read() from (or after) the end of a file, and because of that, it's called "end-of-file".

But there are the odder cases too, like a terminal, which can return zero bytes on one call (if the user hits ^D on a empty line, or after another ^D), but then return more data on the next read. And datagram sockets, that may support zero-byte datagrams, and the system will return zero bytes for such a datagram, but still return the next datagram on the next call. Also of course you could read() from a file at the end, getting zero bytes, but then try the call again later, and this time find more data waiting. (That would be what an implementation of tail -f might do.)

You can't really "print EOF", since there's nothing to print. It's just the lack of data.

Knowing that cat exits on EOF, you could of course do something like

(cat /dev/null; echo EOF) | whatever...

to print something after the end. Not that it's very useful, IMO.

See:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.