The xargs command in Linux reads items from standard input and passes them as arguments to another command. It bridges the gap between commands that produce output and commands that expect arguments — making it essential for shell pipelines.
xargs reads items from stdin, splits them on whitespace or newlines, and runs the specified command with those items as arguments. If no command is given, xargs defaults to /bin/echo.
The syntax is:
bashxargs [OPTIONS] [COMMAND [initial-arguments]]
A basic example: pass three filenames through a pipe and create them with touch:
bashecho "file1 file2 file3" | xargs touch
This runs touch file1 file2 file3 as a single call.
To see the generated command printed to stderr before it runs, add -t (verbose):
bashecho "file1 file2 file3" | xargs -t touch
-t writes to stderr, not stdout — the debug output does not pollute pipeline results.
For destructive operations, use -p (interactive) to require confirmation before each command. Type y or Y to run it, anything else to skip:
bashecho "file1 file2 file3" | xargs -p rm
Limit arguments per invocation with -n. Instead of passing all items at once, -n 1 runs the command once per argument:
bashecho "file1 file2 file3" | xargs -n 1 -t touch
touch is called three separate times. Useful when the target command does not accept multiple arguments.
Use a placeholder with -I to control exactly where each argument appears in the command. -I % defines % as the replace-str — every occurrence of % in the command template is replaced by the current argument:
bashecho "file1 file2 file3" | xargs -I % sh -c '{ touch %; ls -l %; }'
This runs two commands per argument using sh -c. You can use any string as the placeholder (%, {}, ARGS).
Set a custom delimiter with -d. By default, xargs splits on whitespace. To split on semicolons:
bashecho "file1;file2;file3" | xargs -d \; touch
The delimiter can be a single character or a backslash escape sequence like \n or \t.
Read from a file with -a and process one line at a time with -L 1:
bashxargs -t -L 1 -a ips.txt ping -c 1
Without -L 1, all addresses would be passed to a single ping call. -L 1 reads one line per invocation. The difference from -n: -n N limits arguments per invocation regardless of line structure; -L N limits lines per invocation. Use -n for space-separated single-line input; use -L when each item is on its own line.
The most common use of xargs is with find:
bashfind /var/www/.cache -type f -print0 | xargs -0 rm -f
-print0 tells find to separate filenames with null bytes instead of newlines. -0 tells xargs to split on null bytes instead of whitespace.
This is the only safe combination for arbitrary filenames. Spaces, newlines, tabs, and most other special characters can legally appear in a Linux filename. The null byte (\0) is the one character that cannot. Using any other delimiter risks splitting a single filename into multiple parts, causing xargs to operate on the wrong targets.
Before running a destructive command, swap rm -f for echo to preview the target list:
bashfind /var/www/.cache -type f -print0 | xargs -0 echo
Trim whitespace. Since xargs defaults to /bin/echo when no command is given, it works as a whitespace stripper:
bashecho " Long line " | xargs # outputs: Long line
xargs treats leading and trailing whitespace as delimiters and passes only the tokens to echo, which joins them with single spaces.
Always use find -print0 | xargs -0 for file operations. Use -t to verify commands before they execute and -p to confirm destructive operations interactively. Leave a comment below if you run into any issues.