0

Consider the following piece of code:

myprocess | while read line; do logger -t mytag -p user.err $line; done &

if [ ${PIPESTATUS[0]} -ne 0 ]; then
   logger -t ${tag} -p user.error "CANNOT START (exit code: ${PIPESTATUS[0])"
fi

If myprocess does not fail, then the PIPESTATUS[0] is what, undefined? How can I check if myprocess started or died on startup (missing library symbols etc.), while still capturing its output?

Thanks, Dan

1
  • 1
    PIPESTATUS applies to the most recent foreground pipeline. Commented Jan 7, 2014 at 15:40

3 Answers 3

1

How about this:

{ myprocess 2>&1 || echo "CANNOT START (exit code: $?)" ; } \
| while read line; do logger -t mytag -p user.err $line; done

The 2>&1 will let you trap and log error output as well as standard output.

Sign up to request clarification or add additional context in comments.

1 Comment

This does not seem to work if I add an & after the done. The script needs to continue, leaving this in the background.
0

If myprocess did not fail, ${PIPESTATUS[0]} would be 0.

Alternatively, set -o pipefail. Then the exit status of the full command ($?) would be non-zero if myprocess failed and you wouldn't need to check PIPESTATUS.

Comments

0

This can get tricky. You need to return ${PIPESTATUS[n]} from the backgrounded job. I do something very similar by creating a function and passing in the command to run as an argument then send the whole thing to the background. NOTE the return statement in the pipe_command() function. This returns the status of $cmd as opposed to your while read line loop. You can background multiple things in a for loop using this technique as well. Hope this helps.

Example:

#! /bin/bash

main()
{
    pids=""
    myprocess="ssh user@node /bin/bash /etc/init.d/process start"
    pipe_command "$myprocess" &
    pids+="$! "
    watch_pids "$pids"
}

pipe_command()
{
    cmd="$1"
    $cmd 2>&1 | \
    while read line; do
        logger -t mytag -p user.err $line
    done
    return ${PIPESTATUS[0]}
}

watch_pids()
{
    pids="$1"
    for pid in $pids; do
        wait $pid
        if [ $? -ne 0 ]; then
            logger -t ${tag} -p user.error "CANNOT START (exit code: $?)"
            return 2
        fi
    done
}
main $@

Or perhaps more simply put to your example:

myprocess | while read line; do logger -t mytag -p user.err $line; done ; return ${PIPESTATUS[0]} &

wait
status=$?
if [ $status -ne 0 ]; then
   logger -t ${tag} -p user.error "CANNOT START (exit code: $status)"
fi

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.