linuxxargs

Is there a way to take the output of xargs and combine any stderr and stdout into a single line so there is only one line per command run?


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.


Solution

  • 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