Sometimes it's useful to write an xargs command that begins with xargs -I {} 'echo {} | [rest of command]'
in order to redirect the argument as a pipe.
however, for large arguments, you will encounter xargs: argument line too long
.
How do I tell xargs to redirect straight to the os input pipe for [rest of command]
so that I avoid the above issue when using large arguments?
Reproducer:
# create a file with very long base64-encoded lines
seq 1 10 |
xargs -I {} sh -c '
openssl rand -base64 21000000 | tr -d "'"\n"'"; echo
'> out.b64
# now, try to pipe each line into a new instance of a program
# xargs fails at doing this because the lines are too large
cat out.b64 |
xargs -I {} sh -c "echo {} | rest-of-command"
Nothing you're doing calls for xargs at all, anywhere.
#!/usr/bin/env bash
for ((i=0; i<10; i++)); do
openssl rand -base64 21000000 | tr -d '\n'
echo
done >out.b64
while IFS= read -r line; do
{ rest-of-command; } <<<"$line"
done <out.b64
The { rest-of-command; } <<<"$line"
could also be written as printf '%s\n' "$line" | rest-of-command
or < <(printf '%s\n' "$line") rest-of-command
. I don't recommend echo
for the reasons given in Why is printf better than echo?.
xargs is a limited-purpose tool: it transports content from stdin to command-line arguments. If that's not what you mean to accomplish, it's the wrong tool for the job.