help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] How to merge stdout and stderr yet distinguish what is f


From: João Eiras
Subject: Re: [Help-bash] How to merge stdout and stderr yet distinguish what is from stdout and what is from stderr?
Date: Sun, 4 Feb 2018 23:24:04 +0100

Hi !

You have two options

1) easy solution, prepend something to the lines coming from each file
descriptor

( command 1> >(awk '{print "1" $0}') 2> >(awk '{print "2" $0}') ) >
all_my_output.txt

Note: both sub-shells running awk will output to stdout, so both
outputs are merged

2) fancy solution, keep both stdout and stderr separate and handle
them independently.

This code is more complicated, but it conveniently wrapped with a function

function run_command_with_output_handler {
  local output_handler="$1"
  shift

  local p1=/tmp/stdout.pipe.$BASHPID p2=/tmp/stderr.pipe.$BASHPID

  "$@" 1>"$p1" 2>"$p2" &

  (while [[ 1 ]] ; do
    line=
    pipe_broken=0
    timed_out=0

    for fd in 101 102; do
      read -r -t 0.005 -u $fd line
      readstatus=$?

      [[ $readstatus -gt 127 && ${#line} = 0 ]] && timed_out=$(($timed_out + 1))
      [[ $readstatus = 0 || ${#line} != 0 ]] && break
      [[ $readstatus = 1 ]] && pipe_broken=$(($pipe_broken + 1))
    done

    # Both pipes are closed, so the task ended
    [[ $pipe_broken -ge 2 ]] && break

    # Both pipes timed out so so the task has not written anything meanwhile.
    # Find way to use
http://man7.org/linux/man-pages/man2/select.2.html instead of a sleep.
    [[ "$timed_out" = 2 ]] && { sleep 0.05 ; continue ; }

    # Now fd is either 101 or 102 and  $line is not empty, use at will.
    output_handler "${fd:2}" "$line"
  done) 101<"$p1" 102<"$p2"

  wait

  rm -f "$p1" "$p2"
}

function my_output_handler {
  echo "Fd: $1. line: $2"
}

some_command=( lots of stuff here and arguments )
run_command_with_output_handler my_output_handler "address@hidden"

Note: part of this code was just typed in the e-mail and not tested.

Hope this helps.

Cheers.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]