1834131 Members
2086 Online
110064 Solutions
New Discussion

pipes and return codes

 
Jdamian
Respected Contributor

pipes and return codes

Hi

A script contains the following:

function X
{
sed 's/^/### /p'
}

commandB | X

My problem is to catch the code ($?) returned by commandB without using a intermediate file. I need that value to be returned to the parent process (the process that calls my script)

any ideas ?
21 REPLIES 21
Paula J Frazer-Campbell
Honored Contributor

Re: pipes and return codes

Hi

Easiest way is to use a file:-

commandB | >>/tmp/X

Paula
If you can spell SysAdmin then you is one - anon
Paula J Frazer-Campbell
Honored Contributor

Re: pipes and return codes

Hi

Easiest way is to use a file:-

commandB >>/tmp/X

Paula
If you can spell SysAdmin then you is one - anon
Massimo Bianchi
Honored Contributor

Re: pipes and return codes

Hi, try

commandB| echo $? | X


X will get in input the RETCOD.


HTH,
Massimo

Massimo Bianchi
Honored Contributor

Re: pipes and return codes

Hi,
sorry for a mispelling:

(commandB ); echo $? | X


HTH,
Massimo
Jdamian
Respected Contributor

Re: pipes and return codes

Massimo, your proposal won't work, because it is equivalent to

commandB > /dev/null
echo $? | X

I need the output from commandB BE the input to X.
Massimo Bianchi
Honored Contributor

Re: pipes and return codes

Hi,
so you need both the output of the command and the retcode, is this correct ?

Massimo

Jdamian
Respected Contributor

Re: pipes and return codes

Yes, I need both
Hai Nguyen_1
Honored Contributor

Re: pipes and return codes

Try this:

# (commandB; echo $? > /tmp/rc.txt) | X

commandB's output is passed thru the pipe while its return code is saved in /tmp/rc.txt

Hai
Darren Prior
Honored Contributor

Re: pipes and return codes

Hi,

How about putting commandB into a function too, ie:

function commandBfunction
{
commandB
retcodeB=$?
}

You can then use retcodeB elsewhere in the script.

regards,

Darren.
Calm down. It's only ones and zeros...
Jdamian
Respected Contributor

Re: pipes and return codes

function Z
{
commandB
RVAL=$?
}

Z | X

return $RVAL


Darren, it's a good idea but it still doesn't work because Z and X are run in two subshells. See the manual pages of sh-posix(1):

A pipeline is a sequence of one or more commands separated by a bar
(|) and optionally preceded by an exclamation mark (!). The standard
output of each command but the last is connected by a pipe (see
pipe(2)) to the standard input of the next command. Each command is
run as a separate process; the shell waits for the last command to
terminate.
Hai Nguyen_1
Honored Contributor

Re: pipes and return codes

Actually this code should be what you expect.

Rewritten function X:
function X
{
RC=`echo $?`
sed 's/^/###/p'
}

Rewrite "commandD | X" to:

export RC
commandB | X
echo $RC # this is the return code of commandB

Hai
Massimo Bianchi
Honored Contributor

Re: pipes and return codes

Hi,
use


export RETVALB=$?


should to the final trick.

HTH,
Massimo

Jdamian
Respected Contributor

Re: pipes and return codes

The problem is the pipe...
Hai Nguyen_1
Honored Contributor

Re: pipes and return codes

OK. How about this:

function Z
{
commandB
RVAL=$?
}

export RVAL
Z | X
echo $RVAL

This should be independent of the pipe and should always work since RVAL is a global variable.

Hai
Jdamian
Respected Contributor

Re: pipes and return codes

No, Hi... it doesn't work...

For executing Z, the shell runs a subshell. RVAL value is changed in this subshell. Thus, when subshell dies, its RVAL variable is destroyed.

I think the only solution is using an intermediate file.
Darren Prior
Honored Contributor

Re: pipes and return codes

I see the point - it doesn't work for the same reason that my idea didn't work! ;-(

Although it's more messy, I think that dumping the return code into a file is your best option, though it's been fun trying to find ways round it!

regards,

Darren.
Calm down. It's only ones and zeros...
Hai Nguyen_1
Honored Contributor

Re: pipes and return codes

function Z
{
commandB
RVAL=`echo $?`
}

export RVAL
Z | X
echo $RVAL

I caught the error in function Z. RVAL=$? is corrected to RVAL=`echo $?`

Hai
Massimo Bianchi
Honored Contributor

Re: pipes and return codes

It works:

The trick is the subshell, you put both output to the suvsequent command. When you want to test the RETCOD, you seach with awk for it.

[massimo@localhost massimo]$ (ls infos.txt; echo RETCODE=$?) | grep -v ciccio
infos.txt
RETCODE=0
[massimo@localhost massimo]$ (ls infos1.txt; echo RETCODE=$?) | grep -v ciccio
ls: infos1.txt: No such file or directory
RETCODE=1
[massimo@localhost massimo]$



As you can see:

- no file
- both output of the command, standard error, and return code are echoed to the command after the pipe.


HTH,
Massimo
Jean-Louis Phelix
Honored Contributor

Re: pipes and return codes

hi,

I've tried ... like others :-), but with no success, and I can't see any 'generic' way of doing it without a temp file. Some solutions will work depending of the command on the right side of the pipe, but it's always easy to find a pipe command which wouldn't work ... For example, if I need to grep ALL output from the left side, no solution using echo $? can work.

Sorry for you ...

It works for me (© Bill McNAMARA ...)
Rory R Hammond
Trusted Contributor

Re: pipes and return codes

X()
{
cat - |
sed 's/^/### /p'
RVAL2=`echo $? xxxxxxxxxxxxxxxxxxxxxxxxx`
RVAL1=`cat RVAL$$;rm RVAL$$`
}

Z()
{
cat /etc/passwd
echo $? yyyyyyyyyyyyyyyyyyy > RVAL$$
}

Z |X
echo XXXXXXXXXXXXXXXXXX $RVAL1 XXXXXXXXXXXXXX
echo XXXXXXXXXXXXXXXXXX $RVAL2 XXXXXXXXXXXXXX

It is not pretty
the cat /etc/passwd is commandB I needed something real.
There are a 100 ways to do things and 97 of them are right
Jean-Louis Phelix
Honored Contributor

Re: pipes and return codes

Hi Rory,

I'm sure it works, but you've cheated :-) He didn't wanted to use a tmp file, and you use RVAL$$. If a tmp file is allowed, you have many simple solutions ...

#!/usr/bin/sh
RETCOD=/tmp/retcod$$
(command ; echo $? > $RETCOD) | sed 's/^/###/' # or any function ...
exit $(cat $RETCOD)

Regards.
It works for me (© Bill McNAMARA ...)