Updated: 3 November 2026 · Applies to: Linux, GNU findutils and coreutils
A pipeline connects one command's output directly to another command's input with the | character, so you can chain small, single purpose tools into one larger operation instead of writing a script. Two of the most useful commands to build pipelines with are xargs, which turns piped input into arguments for another command, and tee, which copies its input to a file while still passing it through unchanged.
The basic pipe syntax
Any command's standard output can feed directly into the next command's standard input:
command1 | command2
You can chain as many as you need:
command1 | command2 | command3
For example, to see only the first lines of the kernel ring buffer instead of the whole thing:
dmesg | head
Using xargs to turn input into arguments
Many commands take their work as command line arguments rather than reading standard input, and xargs bridges that gap by reading lines from a pipe and turning them into arguments for another command. A basic example, collapsing a list onto one line:
ls -1 *.sh | xargs
To run a command once per item in the list, for example counting lines in each matching file:
ls *.sh | xargs wc -l
A common, more serious use is deleting every directory matching a name, anywhere under the current one:
find . -name "old-backups" -type d -print0 | xargs -0 rm -rf
find's -print0 separates results with a null character instead of a newline, and xargs's -0 reads them the same way, so the command works correctly even if a file or directory name contains a space.
By default xargs runs the command once with as many arguments as will fit on one command line. To run several in parallel instead, add -P with the number of jobs:
find . -name "*.log" -print0 | xargs -0 -P 4 gzip
Using tee to save output while still watching it
tee reads its input and writes it both to standard output and to a file, so you can watch a command run and keep a copy of the result at the same time, without running it twice. For example, to see the heaviest processes by memory while also saving the list:
ps -eo cmd,pid,ppid,%mem,%cpu --sort=-%mem | head | tee topprocs.txt
Check the saved copy:
cat topprocs.txt
To append to an existing file instead of overwriting it, add -a:
ps -eo cmd,pid,ppid,%mem,%cpu --sort=-%mem | head | tee -a topprocs.txt
tee can also write to more than one file in the same command, or pipe its output on to a further command, since it still passes everything through to standard output.
Both tools have a lot more options than are covered here; their manual pages have the full list:
man xargs man tee