10

According with the FHS about /dev at:

it contains:

The following devices must exist under /dev.

/dev/null All data written to this device is discarded. A read from this device will return an EOF condition.

/dev/zero This device is a source of zeroed out data. All data written to this device is discarded. A read from this device will return as many bytes containing the value zero as was requested. ...

Observe that both have:

All data written to this device is discarded

I read many tutorials where /dev/null is always used to discard data. But because both have the same purpose about writing (discard)

Question

  • When is mandatory use /dev/zero over /dev/null for write/discard purpose?

BTW for other differences - practically mostly about read - we have available:

Manuel Jordan
  • 1,728
  • 2
  • 16
  • 40
  • 2
    Why do you think it would ever be mandatory? (Well, apart from constructed cases like a chroot environment that doesn't have null but has zero, I guess.) – ilkkachu Apr 14 '22 at 20:29
  • Perhaps mandatory for some scenarios where performance and blocking would be involved. – Manuel Jordan Apr 14 '22 at 21:37

3 Answers3

47

If you're using Linux, it's never "mandatory" to redirect to /dev/null instead of /dev/zero. As you've noticed, you'll get the same result either way.

That said, you should always redirect to /dev/null if you're discarding data. Because everyone understands that writing to /dev/null means throwing the data away; it's expressing your intention.

On the other hand, writing to /dev/zero also throws your data away, but it's not immediately obvious that that's what you're trying to do.

Besides that, I'd be concerned whether writes to /dev/zero are allowed on other Unices, like the BSDs etc. I don't think /dev/zero is even required by POSIX, while /dev/null is. So using /dev/null for its intended purpose is maximally portable; doing anything else is sacrificing portability for no gain.

Nick Matteo
  • 1,485
  • 1
    Interesting - here comes a secondary question: What was the purpose to allow write/discard to dev/zero if /dev/null offers the same approach – Manuel Jordan Apr 14 '22 at 12:48
  • 2
    @ManuelJordan I don't know for sure, but probably because not allowing it would've taken extra work, while allowing it worked by default and didn't cause issues. – Egor Hans Apr 14 '22 at 13:04
  • 12
    If I had to construct a reason on the fly, I'd say it would have to do with the ability to open /dev/zero in read-write mode. You can at least read something from /dev/zero, something you can't do with /dev/null. – chepner Apr 14 '22 at 13:18
  • 6
    I'll bet they actually share much of the code in the kernel drivers. The only difference between them is how they respond to reads. – Barmar Apr 14 '22 at 14:07
  • 6
    @ManuelJordan: I went looking for a justification when it was implemented. I found that the kernel function for writes to /dev/zero was unified with the one handling writes to /dev/null in this patch in 1993 and hasn't been touched since. The ability to write to /dev/zero seems to have been added in this commit in October 1992 without comment. – Nick Matteo Apr 14 '22 at 18:01
  • @EgorHans I can tell you as a Linux device driver programmer, it takes more work to add the function that handles reading the data and then doing nothing with it, than to leave that function entry NULL. – studog Apr 14 '22 at 20:21
  • @studog, not much more though, when you can just point to the same no-op function /dev/null anyway has... – ilkkachu Apr 14 '22 at 20:26
  • @ilkkachu I was curious so I'm looking at drivers/char/mem.c right now, and there are different -- nope! It's the same function behind both, there's a #define changing the name for the zero device. Which pre-dates git, so that's as far as I'm digging. – studog Apr 14 '22 at 20:46
  • @NickMatteo thanks for the links, in the beginning I thought the same - about historical reasons. But even with that - "without matter" what device was created before than the other - both offers the same job. I thought the answer would be about performance reasons. But seems it is not the case. Interesting this situation. Anyway we already have some standards throughout these years for them, one for reading and other for writing – Manuel Jordan Apr 14 '22 at 21:36
  • @studog: I already posted links to the commit where that define was added, and to when the write_zero function was added before the define! – Nick Matteo Apr 14 '22 at 23:06
8

There is a use case: if a program detects its stdout is directed into /dev/null and alters its behavior (which is not very Unix-way, in my opinion), and you don't want that.

I know only one example: tar. Imagine you want to ensure all files in some directory are actually readable from the disk (no I/O errors, etc.). One way to do it is to tar them to /dev/null:

tar -cv dir/ > /dev/null

But if you try it you may find that tar doesn't actually read the contents of the files, only the metadata (the command runs way too fast). And

tar -cv dir/ > /dev/zero

does read the files' contents (runs slower, with more disk reads).

Roman
  • 181
  • Hngh, yep, that's a hilarious behaviour. Another way to work around it is to pipe to /dev/null through cat. Also works if you want prevent the software from detecting it's connected to a terminal. – ilkkachu Apr 16 '22 at 16:18
4

There is no mandatory cases, but there are use cases:

  • /dev/null: is often used when you need to provide a file name, but you do not care about the data.

    Often this is used on stdout: you do not want output of a program, so you redirect the output to /dev/null (so it is discarded). Very convenient on scripts (and cronjob), where you check the status, but text will just confuse.

    You can read /dev/null to create a empty file (but other syntaxes may be better e.g. : > empty_file_name), or when I just want the headers of a table, but I do not want to deliver data

  • /dev/zero: I use it when I should *physically" erase data, e.g. with dd command: I override an hard-disk with zeros. Zeros is never ending, so it will override all the hard disk, without having a original file (or occupy space). Alternate it is to use /dev/random but it will much slower.

    I do not remember I wrote to /dev/zero (it seems /dev/null has a better name).

Note: /dev/zero will continue to feed data (and it tell program that it has data). /dev/null instead (when used as input) just tell the program that there are no more data).

It is interesting the documentation you linked. As you see /dev/null is usually used to write, and /dev/zero to read (it according with the first case for each one listed on documentation).

In general: when we are creating a script, we may find new way to use them. It depends on what I'm doing, and what parameters are required by a specific programs. We have also yes command, which deliver us y (with a new line), when we need to feed many confirmation to programs.

Manuel Jordan
  • 1,728
  • 2
  • 16
  • 40