xargs
Overview
xargs builds and executes command lines from standard input. It bridges tools that emit lists (files, IDs, URLs) to commands that expect argv parameters. Essential in pipelines with find, git, and text filters — and easy to get wrong with spaces or special characters unless you use NUL-delimited mode.
Syntax
command | xargs [options] [utility [args...]]
xargs [options] -a file [utility [args...]]If utility is omitted, xargs defaults to /bin/echo.
Common Options
| Option | Description |
|---|---|
-0 / --null |
Input items are NUL-separated (safe for arbitrary filenames) |
-n N |
At most N args per command invocation |
-n 1 |
One arg per invocation |
-P N |
Run up to N processes in parallel |
-I {} |
Replace {} in the command template with each item |
-i |
Like -I {} (deprecated form on some systems) |
-t |
Print the command before running it |
-p |
Prompt before each command |
-r |
Do not run if stdin is empty (GNU) |
-d delim |
Input delimiter (GNU) |
-L N |
Use at most N lines per command |
-a file |
Read items from file instead of stdin |
-x |
Exit if a single item is too long for the command line |
Safety
- Never pipe raw
findoutput into barexargswhen names may contain spaces or newlines. Usefind … -print0 | xargs -0 …. xargssplits on whitespace by default — a filenamemy file.txtbecomes two arguments.- Parallel
-Pcan overwhelm disks, APIs, or remote hosts; start low. - Interactive prompts (
-p) are for humans; do not use in unattended scripts without care.
Examples with Explanations
Basic: echo words as args
echo 'one two three' | xargs
# runs: echo one two threeDelete files listed by find (NUL-safe)
find /tmp -name '*.tmp' -print0 | xargs -0 rm -fEquivalent modern find:
find /tmp -name '*.tmp' -deleteOne invocation per item with placeholder
find . -name '*.md' -print0 | xargs -0 -I {} cp {} /backup/docs/-I {} forces one item at a time and allows the placeholder anywhere in the command.
Limit batch size
cat ids.txt | xargs -n 50 echo
# or feed a real tool:
cat ids.txt | xargs -n 100 my-bulk-api-deleteAvoids “argument list too long” and huge single CLI lines.
Parallel compression
find . -type f -name '*.log' -print0 \
| xargs -0 -P 4 -n 1 gzipFour gzip workers, one file each.
Show commands (-t) while learning
printf 'a\nb\nc\n' | xargs -n 1 -t rm -fSkip empty input (GNU)
grep -rl 'obsolete' . | xargs -r rm
# better NUL-safe:
grep -rlZ 'obsolete' . | xargs -0 -r rmWithout -r, some xargs still run the command once with no args — dangerous for rm.
Lines as items (GNU -d)
xargs -d '\n' -n 1 echo < urls.txtStill fails if lines contain embedded newlines (rare); for filenames prefer NUL.
Placeholders with multiple uses
cat hosts.txt | xargs -I% sh -c 'ssh % "hostname; uptime"'Quote carefully; prefer a real loop for complex remote commands.
From a file directly
xargs -a packages.txt -n 1 sudo apt-get install -y(Still review package lists before mass installs.)
Combine with git
git ls-files -z '*.png' | xargs -0 ls -l
git grep -z -l 'TODO' | xargs -0 "$EDITOR"Understanding Output
xargs itself is quiet unless -t/-p is set; you see the utility’s stdout/stderr. Exit status is non-zero if any invocation fails (details vary; with -P, failures can interleave). Use -t when a pipeline “does nothing” — often the built command is not what you expected.
Notes & Pitfalls
- NUL safety is the professional default for file paths:
-print0/-z/-Zupstream +xargs -0. -I {}implies-n 1and disables some batching; good for clarity, slower for huge sets.- Quoting inside
sh -cwith xargs is a common injection footgun — validate input or avoidsh -cwhen possible. - “Argument list too long” (
E2BIG) is exactly what batching with-nfixes. - Busybox or non-GNU xargs may lack
-0,-r,-a,-d, or-P. On Ubuntu GNU findutils xargs, these are available. - For complex per-file logic, a
while IFS= read -r -d '' f; do …; doneloop is often clearer than nested xargs.
Additional Resources
man xargsman find(especially-print0,-exec)