0

We know that:

  1. The pipe operator | is used to take the standard output of left side command as the standard input for the right side process.
  2. The stdout redirection operator > is used to redirect the stdout to a file

And the question is, why cannot ls -la | > file redirect the output of ls -la to file? (I tried, and the file is empty)

Is it because that the stdout redirection operator > is not a process?

Daniel Yi
  • 1
  • 1

1 Answers1

0

Is it because that the stdout redirection operator > is not a process?

In short, yes.

In a bit more detail, stdout, stderr and stdin are special file descriptors (FDs), but these remarks work for every FD: each FD refers to exactly one resource. It can be a file, a directory, a pipe, a device (such as terminal, a hard drive etc) and more. One FD, one resource. It is not possible for stdout to output to both a pipe and a file at the same time. What tee does is takes stdin (typically from a pipe, but not necessarily), opens a new FD associated with the filename provided as its argument, and writes whatever it gets from stdin to both stdout and the new FD. This copying of content from one to two FDs is not available from bash directly.

EDIT: I tried answering the question as originally posted. As it stands now, DevSolar's comment is actually more on point: why does > file, without a command, make an empty file in bash?

The answer is in Shell Command Language specification, under 2.9.1 Simple commands. In the first step, the redirection is detected. In the second step, no fields remain, so there is no command to be executed. In step 3, redirections are performed in a subshell; however, since there is no command, standard input is simply discarded, and the empty standard output of no-command is used to (try to) create a new file.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • "It is not possible for stdout to output to both a pipe and a file at the same time." -- [`exec > >(tee -i logfile.txt)`](https://stackoverflow.com/a/3403786/60281) ;-) Well, OK, that is stdout writing to a named pipe running `tee`, a.k.a. cheating, but it does the job. ;-) – DevSolar Mar 29 '22 at 09:25
  • @DevSolar Isn't your example again using `tee` to duplicate the data to both its own `stdout` as well as a new file descriptor, just as I described above? There's still only one resource per FD. – Amadan Mar 29 '22 at 09:31
  • But the `stdout` of the running process now outputs to both a file and the terminal. Yes I know that strictly speaking you still only have one resource (the named pipe) per FD (stdout), but I wanted to point out that it is possible to *effectively* have a built-in `tee`. – DevSolar Mar 29 '22 at 09:56