28

I see that this has the behavior:

[root@divinity test]# echo 0 > file.txt
[root@divinity test]# cat file.txt
0
[root@divinity test]# echo 0> file.txt

[root@divinity test]# cat file.txt

I also noticed that if I include "" then it works as expected:

[root@divinity test]# echo 0""> file.txt
[root@divinity test]# cat file.txt
0

I imagine this is all just part of IO redirection, but I do not quite understand what echo 0> is doing.

schrodingerscatcuriosity
  • 12,087
  • 3
  • 29
  • 57
Kahn
  • 1,652
  • 2
  • 19
  • 36
  • @zevzek "nohup experts" -- assuming bash or a shell with equivalent extensions, why would any expert use `nohup` instead of explicit redirection and `disown -h`? (Honest question: I suspect I may learn something from your response). – Charles Duffy Oct 10 '21 at 18:17
  • @Charles see [this Q&A on `nohup` v. `disown`](https://unix.stackexchange.com/q/3886/86440). – Stephen Kitt Oct 10 '21 at 18:45
  • @StephenKitt, ...hmm. That's comparing `nohup` against `disown` _without redirection_, whereas it's `disown` _with redirection_ (for all three of the standard FDs) that I'd call a fair comparison. Thus, almost all of the time spent in the analysis above is about the results of the subprocesses still inherting stdin/stdout/stderr. – Charles Duffy Oct 10 '21 at 18:51
  • @zevzek I sit corrected, thanks. – Stephen Kitt Oct 11 '21 at 13:02
  • @zevzek What does using a subshell have to do with not needing to redirect stdin from `/dev/null`? – jrw32982 Oct 13 '21 at 21:15

2 Answers2

57

In echo 0 > file.txt, with the spaces, > file.txt causes the shell to redirect standard output so that it is written to file.txt (after truncating the file if it already exists). The rest of the command, echo 0, is run with the redirections in place.

When a redirection operator is prefixed with an unquoted number, with no separation, the redirection applies to the corresponding file descriptor instead of the default. 0 is the file descriptor for standard input, so 0> file.txt redirects standard input to file.txt. (1 is standard output, 2 is standard error.) The number is treated as part of the redirection operator, and no longer as part of the command’s arguments; all that’s left is echo.

You can see this happening more obviously if you include more content in the echo arguments:

$ echo number 0 > file.txt
$ echo number 0> file.txt
number

number shows up in the second case because standard output isn’t redirected.

This variant of the redirection operator is more commonly done with standard error, 2> file.txt.

Redirecting standard input in this way will break anything which actually tries to read from its standard input; if you really want to redirect standard input, while allowing writes, you can do so with the <> operator:

cat 0<> file.txt
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
-1

File descriptor zero is the input stream. 0>filename will place the input stream into filename. 0 > filename will put 0 into the file filename. Notice the spacing.