I am trying to understand how pipes |
work; in particular, in what way the output from the left command is passed as the input to the right command. Is the output from the left command treated as a file that is passed as an argument to the right command, i.e., is
a | b
the same as
a > a_output
b a_output
This would mean that b
takes a filename as input and reads it. But this would seem to make things like
cat wonderfulfile | tr 'a-z' 'A-Z'
impossible, since tr
does not take a filename as input. Or is the output of the left command treated as standard input for the right command, i.e., if
a
prints
f
g
h
to the screen, is
a | b
the same as
b
f
g
h
^D
or perhaps
b f g h
or
b 'f g h'
This would seem to contradict lines like
who | less
since less, at least without options, requires a filename. Thank you for your help.
2 Answers 2
It’s the second option: in
a | b
anything that a
outputs to its standard output is provided on b
’s standard input.
Your perceived contradiction isn’t one: less
without options reads from its standard input (unless it’s a terminal, in which case it fails), without requiring a file name.
-
$ less Missing filename ("less --help" for help) $ less f f: No such file or directory
Mr. Man– Mr. Man2023年04月17日 17:41:59 +00:00Commented Apr 17, 2023 at 17:41 -
Try actually piping something into it, e.g.
who | less
as in your own example.Stephen Kitt– Stephen Kitt2023年04月17日 17:45:40 +00:00Commented Apr 17, 2023 at 17:45 -
Yes, but I am trying to understand what is the equivalent of piping. Is the output of who taken as an argument to less, like
less $(who)
, which doesn't seem to work, or if it is taken as standard input as if you typed less, pressed Enter, and then starting typing things, why doesless
fail when I type it on its own?Mr. Man– Mr. Man2023年04月17日 17:53:26 +00:00Commented Apr 17, 2023 at 17:53 -
less
checks whether its standard input is a terminal; if it is, it requires a file name, but if it isn’t, it reads from it. Tryless <<<Hello
.Stephen Kitt– Stephen Kitt2023年04月17日 18:07:21 +00:00Commented Apr 17, 2023 at 18:07 -
1I can’t find it documented, it’s visible in the
less
source code.Stephen Kitt– Stephen Kitt2023年04月17日 21:40:38 +00:00Commented Apr 17, 2023 at 21:40
Is the output from the left command treated as a file that is passed as an argument to the right command
No.
The pipe connects the standard output to the standard input. That's really what it does. Just as your >
redirects the standard output to a file, |
redirects the standard output stream into the stream that is the standard input of the second command.
In other words, whenever program b
does something like read
ing from the input, it reads what a
has put onto its output. No file in between – the pipe is the integral "connection" between the output and the input. "standard output" and "standard input" are two streams every program has under a UNIX-style operating system (and also, most other operating systems for PC-style hardware).
-
What about programs like
less
, which, at least without options specified, require a file as an argument? Inwho | less
, doesn'tless
expect a filename?Mr. Man– Mr. Man2023年04月17日 17:47:35 +00:00Commented Apr 17, 2023 at 17:47 -
It does not require an argument.
less
without a file argument just reads from its standard input.Marcus Müller– Marcus Müller2023年04月17日 19:55:18 +00:00Commented Apr 17, 2023 at 19:55 -
less -
makes it read stdin as a file, and also use the terminal input as command keys (Linux Mint 19.3) with unpleasant results. Needed toCtrl-Z
andkill %1
to end it, asCtrl-C
andCtrl-D
etc are apparently trapped.Paul_Pedant– Paul_Pedant2023年04月17日 20:54:17 +00:00Commented Apr 17, 2023 at 20:54
less
and other programs "knows" when input and/or ouput are a terminal, a file or a pipe and can behave accordingly.