LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Bash : preserve return value through pipe (http://www.linuxquestions.org/questions/programming-9/bash-preserve-return-value-through-pipe-4175455891/)

Ramurd 03-28-2013 06:45 AM

Bash : preserve return value through pipe
 
The answer is eluding me, my apologies for this silly question :-)

I have a function logger that will log to screen or file based on some variables. This function kind of works, but provides a nasty thing: the return value of the calling command is lost (as one could expect);

I tried to solve it like this:
Code:

#!/bin/bash

logger()
{
        RETVAL=$?
        echo "RETVAL=$RETVAL"
        return $RETVAL
}

false | logger || echo $?

Just as a simple test, to see if I can pipe the output of one command to a new command and keep the return value... The above does not work... Anyone who has a nice thought how I can make my logger function return the return value of the first command?

kbp 03-28-2013 07:01 AM

Sorry, I can't see why you're piping, this works:
Code:

#!/bin/bash

logger()
{
        RETVAL=$?
        echo "RETVAL=$RETVAL"
        return $RETVAL
}

false
logger
echo $?


David the H. 03-28-2013 07:19 AM

Recent versions of bash provide a PIPESTATUS array variable, which holds all the exit codes of the most recent command chain.

"$?" will only hold the exit status of the most recently executed command, which will be the last one in the pipe chain.

Edit: For details, always check the documentation. ;) From the bash man page:

Quote:

The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. If the reserved word ! precedes a pipeline, the exit status of that pipeline is the logical negation of the exit status as described above. The shell waits for all commands in the pipeline to terminate before returning a value.


Ramurd 03-28-2013 07:33 AM

Normally my logger() function would print the output of the provided command to screen, logfile or both (depending on a variable); So the implementation written above was only to illustrate what I tried.

In the specific case I try to do:

Code:

svn export ${SVN_URL} | logger
Given the PIPESTATUS[] array, I should be able to:
Code:


SVN_URL="https://bogus.url"
get_from_svn()
{
    svn export ${SVN_URL} | logger | return ${PIPESTATUS[0]}
}

main()
{

  get_from_svn || (echo "Something went wrong." ; return $?)
}

main $@

however, I seem to do something wrong yet... Thanks for pointing me to PIPESTATUS[] array, I totally forgot about that one.

Ramurd 03-28-2013 07:39 AM

Ah, finally got it :-)

Code:

#!/bin/bash
# do something
#

logger()
{
        read string
        printf "[LOG] %s\n" "${string}"
}

get_from_svn()
{
        svn export https://bogus.url 2>&1 | logger
        STATUS=${PIPESTATUS[0]}
        echo "Status: ${STATUS}"
        return ${STATUS}
}

main()
{
        get_from_svn
        echo "Returned: $?"
}

main



All times are GMT -5. The time now is 02:42 AM.