rpm -qa > file | wc -l
returns 0. What am I doing wrong? I think it is clear what my goal is, but it isn't working. Is this a job for xargs
or tee
?
4 Answers
Yes, this is a job for tee
:
rpm -qa | tee file | wc -l
Shell redirection (>
) is just that — redirection — and you can only point the output stream to one other place at a time. There's nothing left for the |
to see at that point. tee
is made for just this purpose, where you want to split the stream into two parts, one going into a file and one still on standard output. The above command does exactly what you were trying to do.
xargs
won't help here.
Yes, this is job for tee:
rpm -qa | tee file | wc -l
In this construction a | b
a's stdout goes to stdin of b. In case of a > file | b
all output form a goes to file and nothing goes to b stdin. tee
command make a copy of all it receives on stdin to both file and stdout.
In any shell that's compatible with Bourne or POSIX, redirections are processed from left to right, and the pipe comes first. Thus your command is executed in this way (I omit what happens in subprocess 2):
- Create a pipe.
- Fork two subprocesses, 1 and 2.
- Redirect the standard output of 1 to the pipe.
- Redirect the standard output of 1 to
file
. - In 1, execute
rpm -qa
.
If you want the output of subprocess 1 to be replicated on two channels (the file and the pipe), then someone has to do the job of making two copies of the data. This is exactly what tee
is for.
rpm -qa | tee file | wc -l
Zsh has a built-in feature for output replication, called multios. In zsh (and only in zsh with the multios
option left on, not in POSIX-compliant shells nor in pre-POSIX Bourne shells, nor in (t)csh for that matter), a command like the one you wrote does replicate the data on the two output redirections.
# in zsh
rpm -qa >file | wc -l