What is xargs in Linux
What is xargs in Linux: 20 practical examples
The xargs command builds command lines from standard input. It’s one of those tools that seems simple until you need it, then it becomes indispensable. I use xargs daily for batch operations, and once you understand these patterns, you will too.
Let me walk through the examples I actually use.
Handling “Argument list too long” errors
You’ve probably seen this when trying to delete lots of files:
rm *.log
bash: /bin/rm: Argument list too long
xargs bypasses the argument limit by processing inputs in batches:
find ~ -name '*.log' -print0 | xargs -0 rm -f
The -print0/-0 combo handles filenames with spaces or special characters. I’ll explain why that matters later.
Formatting output
Turn multi-line output into a single line:
ls -1 Images/bitslovers/ | xargs
This is handy when you need to pass a file list as arguments to another command.
Counting lines in multiple files
ls *upload* | xargs wc
This runs wc on each file, giving you line/word/character counts for the whole batch.
Finding and removing files
Recursively remove specific files (this removes the file, not directories):
find . -name "bitslovers_backup" -type f -print0 | xargs -0 /bin/rm -v
Note: I removed the -rf flags from the original example. Using -rf with xargs is overkill and dangerous—let xargs handle the recursion through find.
Handling spaces in filenames
The original post had this wrong. Let me fix it.
If you have a file named “file 1.log”, this fails:
find ./log -type f | xargs rm
# rm: cannot remove './log/file': No such file or directory
# rm: cannot remove '1.log': No such file or directory
xargs splits on spaces by default, so “file 1.log” becomes two arguments. Fix it with -I:
find ./log -type f | xargs -I % rm "%"
Or better yet, use -print0/-0 (I’ll show you why):
find ./log -type f -print0 | xargs -0 rm
Dealing with quotes in filenames
Filenames with quotes break xargs in weird ways:
find ./log -type f | xargs rm
# xargs: unmatched double quote; by default, quotes are special to xargs unless you use the -0 option
Quoting the placeholder doesn’t help—xargs still chokes on the quotes.
The fix: Use null separators instead of newlines:
find ./log -type f -print0 | xargs -0 rm
-print0 terminates filenames with null bytes. -0 tells xargs to expect null-terminated input. This handles spaces, quotes, newlines—anything.
Some commands can’t accept null input (head, tail, ls, wc, sed). For those, you’re stuck with the -I placeholder approach.
Creating archives from found files
find Images/bitslovers/ -name "*.jpg" -type f -print0 | xargs -0 tar -cvzf image.tar.gz
Copying a file to multiple directories
echo ./Blog/ ./Documents/ | xargs -n 1 cp -v ./Downloads/bitslovers-best-way-to-use-xargs.xlsx
-n 1 runs cp once per directory.
Renaming files to lowercase
The original example had syntax issues. Here’s a working version:
find Documents -depth -name '*[A-Z]*' | while read file; do mv "$file" "$(dirname "$file")/$(basename "$file" | tr 'A-Z' 'a-z')"; done
Actually, that’s messy. Let me use a more practical approach with the rename command:
find Documents -depth -name '*[A-Z]*' -exec rename 'y/A-Z/a-z/' {} +
(Assuming you have the Perl-based rename utility installed.)
Reading input from a file
xargs -a bitslovers_links.txt wget -c
Use -a to read from a file instead of stdin. Great for batch downloads.
Verbose mode
See what xargs is about to run:
find . -name "*.conf" | xargs -t ls -l
-t prints each command to stderr before executing it. Useful for debugging.
Interactive mode
Prompt before running each command:
echo ./Blog/ ./Documents/ | xargs -p -n 1 cp -v ./Downloads/file.xlsx
Type y to execute, n to skip. Combine with -t to see the full command first.
Parallel execution
This is xargs superpower. Run commands in parallel:
find . -name "*.jpg" | xargs -P 4 convert -resize 50% {}
-P 4 runs up to 4 processes simultaneously. Perfect for CPU-intensive operations on multi-core systems.
You can even adjust parallelism on the fly with signals (SIGUSR1 increases, SIGUSR2 decreases). Though honestly, I rarely use that—I just pick a good -P value upfront.
Inserting arguments anywhere
By default, xargs appends arguments to the end of the command. Use -I to place them anywhere:
find ./log -type f -name "*.log" | xargs -I % mv % tmp/
You can use any placeholder string—I like % but {} is common too.
Listing all users
cut -d: -f1 < /etc/passwd | sort | xargs
Turns a column of usernames into a space-separated list.
Using custom delimiters
printf "file1.txt\nfile2.txt\nfile3.txt" | xargs -d '\n' -I {} cp {} /backup/
-d lets you specify any delimiter. Though honestly, -0 is safer for most use cases.
Kubernetes: Delete pods by pattern
kubectl get pods -n namespace | awk '{print $1}' | grep "pods-name*" | xargs kubectl delete pod
List pods → extract names → filter → delete. Classic pipeline.
Things I’ve learned the hard way
1. Always use -print0/-0 for file operations
Newlines are valid characters in Unix filenames. Spaces are common. Null bytes are the only safe delimiter.
2. The -i flag is deprecated
Use -I instead. Same functionality, POSIX standard.
3. xargs doesn’t know about exit codes
If a command fails, xargs keeps going. Check exit codes explicitly if you need to stop on errors:
find . -type f | xargs -I {} sh -c 'command "{}" || exit 255'
4. Some commands can’t handle null separators
Commands like head, tail, ls, wc, and sed don’t support -0. For those, you’re stuck with newlines and -I.
5. Parallel xargs processes share stdout
If you use -P, output from different processes gets mixed together. Redirect to files or use --process-slot-var to separate output.
New in recent versions
Since the original post (2021), a few things changed:
- POSIX standardization:
-print0and-0will be standardized in POSIX Issue 8 - Better signal handling:
xargs -Pno longer changes SIGUSR1/SIGUSR2 handling unless you actually use-P - Improved child process handling:
xargs -Pnow waits for all children to complete, even if one exits with status 255 - Deprecated options:
-land-iare deprecated—use-Land-Iinstead
Check man xargs for the full story on your system.
When to use xargs (and when not to)
Good for xargs:
- Simple command execution on found files
- Parallel processing with
-P - Building command lines from lists
- Bypassing argument length limits
Better alternatives:
find -exec ... +for simple operations (fewer processes)find -execdir ... {} +for security (runs in file’s directory)- Shell loops for complex logic
- GNU parallel for advanced parallelization
Conclusion
xargs has been around since the 1980s, and it’s still relevant because it solves a fundamental problem: how do you turn data into commands?
The examples I showed are starting points. Once you understand the patterns—-print0/-0 for files, -I for argument placement, -P for parallelism—you’ll find yourself reaching for xargs constantly.
Just remember: use null separators for filenames, test with -t before running destructive commands, and check man xargs when you need something beyond the basics.
The xargs manual page has more examples than I could fit here. Go explore.
Comments