xargs - Street Ops¶
Real-world xargs patterns pulled from production incidents, migrations, and daily operations.
Quick Diagnosis Commands¶
# Check ARG_MAX on this system (max bytes for a single command line)
getconf ARG_MAX
# See how many arguments xargs will batch by default
echo | xargs --show-limits 2>&1 | head -5
# Test what xargs will do without executing (dry run)
echo "a b c d" | xargs -t -n 2 echo 2>&1
# Count items that will be processed
find /var/log -name '*.gz' | wc -l
# Verify null-delimited pipeline works end to end
find /tmp -name '*.tmp' -print0 | xargs -0 -t echo 2>&1 | head
Common Scenarios¶
Bulk File Operations¶
Mass rename during a migration¶
# Rename all .yml files to .yaml across a project
find /opt/app/config -name '*.yml' -print0 | \
xargs -0 -I {} bash -c 'mv "{}" "${1%.yml}.yaml"' _ {}
# Add a date prefix to all files in a directory
ls /data/exports/*.csv | \
xargs -I {} bash -c 'mv "{}" "$(dirname {})/$(date +%Y%m%d)_$(basename {})"'
# Flatten a nested directory structure (move all files to one dir)
find /data/nested -type f -print0 | xargs -0 -I {} mv {} /data/flat/
Bulk permission fixes after a bad deploy¶
Under the hood:
xargswithout-print0/-0splits on whitespace and newlines. A filename containing a space likemy file.logbecomes two arguments. Always pairfind -print0withxargs -0in production scripts -- this is the only safe combination for arbitrary filenames.
# Fix file permissions (files should be 644, not 755)
find /var/www/html -type f -print0 | xargs -0 chmod 644
# Fix directory permissions
find /var/www/html -type d -print0 | xargs -0 chmod 755
# Fix ownership recursively (faster than chown -R for large trees)
find /opt/app -print0 | xargs -0 chown appuser:appgroup
# Remove setuid/setgid bits from uploaded files
find /data/uploads -type f \( -perm -4000 -o -perm -2000 \) -print0 | \
xargs -0 chmod ug-s
Disk space recovery¶
# Find and remove core dumps
find / -name 'core' -o -name 'core.*' -o -name '*.core' 2>/dev/null | \
xargs -r rm -f
# Truncate (not delete) large log files to reclaim space without breaking open handles
find /var/log -name '*.log' -size +1G -print0 | \
xargs -0 -I {} truncate -s 0 {}
# Remove old rotated logs
find /var/log -name '*.gz' -mtime +30 -print0 | xargs -0 rm -f
# Find large files consuming disk and list them by size
find / -xdev -type f -size +500M -print0 2>/dev/null | \
xargs -0 ls -lhS | head -20
Parallel API Calls¶
Health checking a microservice fleet¶
# Check health endpoints across all services
kubectl get svc -A -o jsonpath='{range .items[*]}{.metadata.name}.{.metadata.namespace}.svc.cluster.local{"\n"}{end}' | \
xargs -P 20 -I {} curl -sf -m 3 -o /dev/null -w "%{http_code} {}\n" http://{}:8080/health 2>/dev/null
# Parallel endpoint validation with timeout and retry
cat api-endpoints.txt | xargs -P 10 -I {} bash -c '
for attempt in 1 2 3; do
code=$(curl -sf -m 5 -o /dev/null -w "%{http_code}" "{}" 2>/dev/null)
if [ "$code" = "200" ]; then
echo "OK {} ($code)"
exit 0
fi
sleep 1
done
echo "FAIL {} (last: ${code:-timeout})"
'
Bulk webhook testing¶
# Send test payloads to multiple webhook endpoints
cat webhook-urls.txt | xargs -P 5 -I {} \
curl -sf -X POST -H "Content-Type: application/json" \
-d '{"event":"test","timestamp":"2026-03-19T00:00:00Z"}' \
-w "%{http_code} {}\n" -o /dev/null {} 2>/dev/null
Parallel DNS lookups¶
# Resolve all hostnames in a list, 20 at a time
cat hostnames.txt | xargs -P 20 -I {} bash -c '
ip=$(dig +short {} A | head -1)
echo "{}: ${ip:-NXDOMAIN}"
'
Mass Process Management¶
Kill runaway processes¶
# Kill all processes matching a pattern (safer than killall)
pgrep -f 'stuck_worker' | xargs -r kill -TERM
# Force kill after grace period
pgrep -f 'stuck_worker' | xargs -r kill -TERM
sleep 10
pgrep -f 'stuck_worker' | xargs -r kill -KILL
# Kill all processes owned by a specific user
pgrep -u abandoned_user | xargs -r kill -TERM
# Kill all processes listening on a specific port range
ss -tlnp | awk '/:(808[0-9])/ {print $NF}' | grep -oP 'pid=\K[0-9]+' | \
sort -u | xargs -r kill -TERM
Container cleanup during incidents¶
# Stop all containers in a specific network
docker network inspect bridge -f '{{range .Containers}}{{.Name}} {{end}}' | \
tr ' ' '\n' | grep -v '^$' | xargs -r -I {} docker stop {}
# Remove all containers with a specific label
docker ps -aq --filter label=environment=staging | xargs -r docker rm -f
# Restart all containers that exited with non-zero status
docker ps -aq --filter status=exited --filter exited=1 | \
xargs -r -I {} docker start {}
Log Processing Pipelines¶
Extract and aggregate error patterns¶
# Find all error log files from the last 24 hours and extract unique errors
find /var/log/app -name '*.log' -mtime -1 -print0 | \
xargs -0 grep -h 'ERROR' | \
awk '{$1=$2=""; print}' | sort | uniq -c | sort -rn | head -20
# Search across compressed log archives in parallel
find /var/log/archive -name '*.gz' -print0 | \
xargs -0 -P 8 -I {} zgrep -l 'OutOfMemoryError' {}
# Aggregate request counts by endpoint from access logs
find /var/log/nginx -name 'access.log*' -not -name '*.gz' -print0 | \
xargs -0 awk '{print $7}' | sort | uniq -c | sort -rn | head -30
# Extract slow queries from multiple database log files
find /var/log/postgresql -name '*.log' -print0 | \
xargs -0 grep -h 'duration:' | \
awk -F'duration: ' '$2+0 > 1000 {print}' | sort -t: -k2 -rn | head -20
Building incident timelines¶
# Search all log sources for a specific request ID
find /var/log -name '*.log' -mtime -1 -print0 | \
xargs -0 -P 8 grep -l 'req-abc123' | \
xargs -I {} sh -c 'echo "=== {} ==="; grep "req-abc123" {} | head -5'
# Correlate events across services within a time window
find /var/log/services -name '*.log' -print0 | \
xargs -0 grep -h '2026-03-19T14:3[0-5]' | sort -t'T' -k2
Bulk Permission and Ownership Changes¶
Post-deploy permission hardening¶
# Ensure no world-writable files exist in the application directory
find /opt/app -type f -perm -002 -print0 | xargs -0 -r chmod o-w
# Set correct ownership for uploaded content
find /data/uploads -not -user www-data -print0 | \
xargs -0 -r chown www-data:www-data
# Remove group write from config files
find /etc/myapp -name '*.conf' -print0 | xargs -0 chmod g-w
# Fix SELinux contexts after a file migration
find /var/www/html -print0 | xargs -0 restorecon -v
Database Operations¶
Bulk table maintenance¶
# VACUUM ANALYZE all tables in a PostgreSQL database
psql -d production -t -c \
"SELECT schemaname||'.'||tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema')" | \
sed 's/^ *//' | grep -v '^$' | \
xargs -I {} psql -d production -c "VACUUM ANALYZE {};"
# Export each table to a separate CSV
psql -d analytics -t -c \
"SELECT tablename FROM pg_tables WHERE schemaname='public'" | \
sed 's/^ *//' | grep -v '^$' | \
xargs -P 4 -I {} psql -d analytics -c "\COPY {} TO '/backup/csv/{}.csv' CSV HEADER"
# Run OPTIMIZE on all MySQL tables
mysql -Nse "SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema='mydb'" | \
xargs -I {} mysql -e "OPTIMIZE TABLE {};"
Bulk Redis operations¶
# Delete all keys matching a pattern (safer than FLUSHDB)
redis-cli --scan --pattern 'cache:session:*' | xargs -n 100 redis-cli DEL
# Get TTL for all keys matching a pattern
redis-cli --scan --pattern 'rate_limit:*' | \
xargs -I {} redis-cli TTL {} | paste - -
# Dump key sizes for capacity planning
redis-cli --scan --pattern '*' | \
xargs -I {} redis-cli DEBUG OBJECT {} 2>/dev/null | \
grep -oP 'serializedlength:\K[0-9]+' | \
awk '{sum+=$1; count++} END {printf "Keys: %d, Total: %.2f MB, Avg: %.0f bytes\n", count, sum/1048576, sum/count}'
Operational Patterns¶
Safe Dry Run Pattern¶
Always test destructive operations before executing:
# Step 1: See what will be affected
find /data -name '*.tmp' -mtime +7 -print0 | xargs -0 ls -la
# Step 2: Count items
find /data -name '*.tmp' -mtime +7 | wc -l
# Step 3: Execute with trace
find /data -name '*.tmp' -mtime +7 -print0 | xargs -0 -t rm -f
Batched Operations with Progress¶
# Process in batches with a counter
total=$(find /data -name '*.raw' | wc -l)
find /data -name '*.raw' -print0 | xargs -0 -n 1 -I {} bash -c '
count=$((count + 1))
echo "[$count] Processing: {}"
convert {} {}.processed
'
# Parallel with per-item status
find /data/images -name '*.png' -print0 | \
xargs -0 -P 8 -I {} bash -c '
if convert "{}" -resize 800x600 "/output/$(basename {})"; then
echo "OK: {}"
else
echo "FAIL: {}" >&2
fi
'
Retry Wrapper for Unreliable Operations¶
# Retry each item up to 3 times on failure
cat urls.txt | xargs -P 5 -I {} bash -c '
for i in 1 2 3; do
if curl -sf -m 10 -o "/data/$(basename {})" "{}"; then
exit 0
fi
echo "Retry $i for {}" >&2
sleep $((i * 2))
done
echo "FAILED after 3 attempts: {}" >&2
exit 1
'
Conditional Execution¶
# Only process files that meet a condition
find /data -name '*.csv' -print0 | xargs -0 -I {} bash -c '
lines=$(wc -l < "{}")
if [ "$lines" -gt 1000 ]; then
echo "Processing {} ($lines lines)"
python3 /opt/scripts/analyze.py "{}"
fi
'
# Process only files not already in the destination
find /source -name '*.dat' -print0 | xargs -0 -I {} bash -c '
dest="/dest/$(basename {})"
if [ ! -f "$dest" ]; then
cp "{}" "$dest"
echo "Copied: {}"
fi
'
Pipeline with Error Collection¶
# Run operations and collect failures for review
find /data -name '*.json' -print0 | \
xargs -0 -P 4 -I {} bash -c '
if ! python3 validate.py "{}" 2>/dev/null; then
echo "{}"
fi
' > /tmp/failed-files.txt
echo "$(wc -l < /tmp/failed-files.txt) files failed validation"
cat /tmp/failed-files.txt
Kubernetes Operational Patterns¶
# Evict all pods from a node before maintenance
kubectl get pods --field-selector spec.nodeName=worker-03 -o name | \
xargs -I {} kubectl delete {} --grace-period=30
# Annotate all deployments in a namespace
kubectl get deploy -n production -o name | \
xargs -I {} kubectl annotate {} -n production last-audit="2026-03-19" --overwrite
# Scale down all non-critical deployments (matching a label)
kubectl get deploy -l tier=non-critical -o name | \
xargs -I {} kubectl scale {} --replicas=0
# Collect logs from all pods matching a label
kubectl get pods -l app=api-gateway -o name | \
xargs -P 4 -I {} bash -c 'kubectl logs {} --tail=50 > /tmp/logs/$(echo {} | tr "/" "_").log'
# Force delete stuck terminating pods
kubectl get pods --field-selector status.phase=Terminating -o name 2>/dev/null | \
xargs -r -I {} kubectl delete {} --grace-period=0 --force
Git Operations¶
# Remove all merged branches except main
git branch --merged main | grep -v 'main' | xargs -r git branch -d
# Find all repos with uncommitted changes
find /workspace -name '.git' -type d | \
xargs -I {} bash -c 'cd "{}/.." && if [ -n "$(git status --porcelain)" ]; then echo "DIRTY: $(pwd)"; fi'
# Bulk clone repos from a list
cat repos.txt | xargs -P 4 -I {} git clone {}