I have a long list of symbolic links to python venvs that I would like to run the --version flag on. Some of the links are broken and some of the Python binaries require other versions of glibc than what is on the machine so that will print a multi-line error. My goal is to have the output of xargs, no matter how many lines of stdout or stderr, print a single line per symbolic link, so the output line count matches the input line count.
I've tried just the basic
... | xargs -I {} sh -c "{} --version" 2>&1 | tee output.txt
but it will print multiple lines for multi-line errors, so the resulting line count doesn't match the input line count.
In the comments, I originally suggested:
xargs -I@ sh -c 'echo $(@ --version 2>&1)'
which will squash each run of embedded whitespace into a single space (assuming IFS
has its normal value).
With untrusted input, it would be safer not to embed the input into the shell command (but since you're excuting it, actually all bets are off). Also, spawning a new shell per test is slightly inefficient, and echo
behaviour can be problematic in some cases (it can treat data as options):
while IFS= read -r link; do
"$link" --version 2>&1 | tr -d '\n'
echo
done