xargs is a powerful command-line tool that reads items from standard input and executes commands with those items as arguments. Combined with its parallel execution capability, it becomes an essential tool for batch processing and automation on your server.
Basic xargs Usage
# Basic: pass input as arguments to a command
echo "file1.txt file2.txt file3.txt" | xargs rm
# Read items one per line
find /tmp -name "*.log" | xargs rm
# Handle filenames with spaces (use -0 with find -print0)
find /tmp -name "*.log" -print0 | xargs -0 rm
# Preview what xargs will execute (dry run)
echo "a b c" | xargs -t echo
# echo a b c ← shows the command
# a b c ← shows the output
Controlling Arguments
# Pass one argument at a time (-n 1)
echo "file1 file2 file3" | xargs -n 1 echo "Processing:"
# Processing: file1
# Processing: file2
# Processing: file3
# Use a placeholder for argument position (-I {})
find . -name "*.bak" | xargs -I {} mv {} /backup/
# Limit arguments per command invocation
echo "1 2 3 4 5 6" | xargs -n 2 echo
# 1 2
# 3 4
# 5 6
Parallel Execution
The -P flag runs multiple commands simultaneously, dramatically speeding up batch operations.
# Compress files in parallel (4 at a time)
find /var/log -name "*.log" -size +1M | xargs -P 4 -I {} gzip {}
# Download multiple files in parallel
cat urls.txt | xargs -P 8 -I {} curl -sO {}
# Process images in parallel (resize with ImageMagick)
find ./images -name "*.jpg" | xargs -P $(nproc) -I {}
convert {} -resize 800x600 ./thumbnails/{}
# Ping multiple hosts simultaneously
echo "google.com github.com cloudflare.com" | tr " " "
" |
xargs -P 3 -I {} sh -c "ping -c 3 {} > /tmp/ping-{}.txt 2>&1"
Real-World Server Administration Examples
Bulk File Operations
# Delete old log files (older than 30 days)
find /var/log -name "*.log.gz" -mtime +30 -print0 | xargs -0 rm -v
# Change ownership of thousands of files efficiently
find /var/www -user olduser -print0 | xargs -0 chown newuser:newgroup
# Find and fix file permissions
find /var/www -type f -print0 | xargs -0 chmod 644
find /var/www -type d -print0 | xargs -0 chmod 755
Database Operations
# Dump multiple databases in parallel
mysql -e "SHOW DATABASES" -sN | grep -v "information_schema|performance_schema" |
xargs -P 4 -I {} sh -c "mysqldump {} | gzip > /backup/{}.sql.gz"
# Import multiple SQL files
find /backup -name "*.sql" | xargs -P 2 -I {} sh -c "mysql mydb < {}"
Service Management
# Restart multiple services
echo "nginx php8.3-fpm mysql redis" | tr " " "
" |
xargs -I {} sudo systemctl restart {}
# Check status of multiple services
echo "nginx mysql redis sshd" | tr " " "
" |
xargs -I {} sh -c "echo --- {} --- && systemctl is-active {}"
Combining with Other Commands
# Count lines in all PHP files
find /var/www -name "*.php" | xargs wc -l | tail -1
# Search for a string in specific file types
find /var/www -name "*.php" -print0 | xargs -0 grep -l "deprecated_function"
# Generate checksums for all files
find /var/www -type f -print0 | xargs -0 sha256sum > checksums.txt
Performance Tips
# Use -P $(nproc) to use all available CPU cores
nproc # Shows number of CPU cores
find . -name "*.gz" | xargs -P $(nproc) gunzip
# For very large file lists, batch arguments
# Default xargs batches efficiently, but you can control it:
find /data -type f | xargs -n 100 -P 4 gzip
# Process 100 files per gzip invocation, 4 parallel processes
# Monitor progress with pv (pipe viewer)
find . -name "*.log" | pv -l | xargs -P 4 gzip
Safety Tips
- Always use
-print0with find and-0with xargs to handle special characters in filenames - Use
-t(trace) or-p(prompt) flags to preview commands before execution - Use
echoas a dry run:find . -name "*.tmp" | xargs echo rm - Be careful with
-Pand database operations — too much parallelism can overload MySQL - When in doubt, start with
-P 2and increase gradually