18

Most answers here [1] [2] [3] use a single angle bracket to redirect to /dev/null, like this :

command > /dev/null

But appending to /dev/null works too :

command >> /dev/null

Except for the extra character, is there any reason not to do this ? Is either of these "nicer" to the underlying implementation of /dev/null ?

Edit:
The open(2) manpage says lseek is called before each write to a file in append mode:

O_APPEND
The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2). The modification of the file offset and the write operation are performed as a single atomic step.

which makes me think there might be a tiny performance penalty for using >>. But on the other hand truncating /dev/null seems like an undefined operation according to that document:

O_TRUNC
If the file already exists and is a regular file and the access mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the O_TRUNC flag is ignored. Otherwise, the effect of O_TRUNC is unspecified.

and the POSIX spec says > shall truncate an existing file, but O_TRUNC is implementation-defined for device files and there's no word on how /dev/null should respond to being truncated.

So, is truncating /dev/null actually unspecified ? And do the lseek calls have any impact on write performance ?

27

By definition /dev/null sinks anything written to it, so it doesn't matter if you write in append mode or not, it's all discarded. Since it doesn't store the data, there's nothing to append to, really.

So in the end, it's just shorter to write > /dev/null with one > sign.

As for the edited addition:

The open(2) manpage says lseek is called before each write to a file in append mode.

If you read closely, you'll see it says (emphasis mine):

the file offset is positioned at the end of the file, as if with lseek(2)

Meaning, it doesn't (need to) actually call the lseek system call, and the effect is not strictly the same either: calling lseek(fd, SEEK_END, 0); write(fd, buf, size); without O_APPEND isn't the same as a write in append mode, since with separate calls another process could write to the file in between the system calls, trashing the appended data. In append mode, this doesn't happen (except over NFS, which doesn't support real append mode).

The text in the standard doesn't mention lseek at that point, only that writes shall go the end of the file.

So, is truncating /dev/null actually unspecified?

Judging by the scripture you refer to, apparently it's implementation-defined. Meaning that any sane implementation will do the same as with pipes and TTY's, namely, nothing. An insane implementation might do something else, and perhaps truncation might mean something sensible in the case of some other device file.

And do the lseek calls have any impact on write performance?

Test it. It's the only way to know for sure on a given system. Or read the source to see where the append mode changes the behaviour, if anywhere.

-3

If it's efficiency you want, use command >&- instead. This closes the file descriptor rather than redirecting it, so no time is wasted writing things to it at all.

  • 3
    Don't close streams less than 3. This aliases the std* descriptors with random file descriptors; potentially with catastrophic results. – Joshua Mar 15 '17 at 19:23
  • 7
    If you just close the file descriptor, the program will get errors on every write call, probably leading to annoying error messages and possibly the program terminating before finishing its task. – ilkkachu Mar 15 '17 at 19:29

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.