LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-02-2013, 06:54 PM   #1
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467
Blog Entries: 60

Rep: Reputation: 51
bash: pass a return value down a pipe?


Hi. I am wondering: is it possible somehow to pass a return value down a pipeline in bash (or perhaps another shell scripting language?) A simple example would be something like so:

Code:
false | echo $?
Which would output "1". However, this doesn't work because $? "expands to the exit status of the most recently executed foreground pipeline", which would be the pipeline before the one currently executing.

I was thinking that, if it were possible to pass return values down the pipe, one could use a wrapper program to create some kind of fail-pipe system, where the output of a pipe is either the output of the last command that failed, or the last command if none failed.

Last edited by hydraMax; 01-02-2013 at 07:16 PM.
 
Old 01-02-2013, 07:31 PM   #2
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Hanover, Germany
Distribution: Main: Gentoo Others: What fits the task
Posts: 15,563
Blog Entries: 2

Rep: Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035Reputation: 4035
I don't really see why you want to use a pipe here. A pipe is used to pass output of a program to another program. If the return code is all you need there is no need for a pipe at all, just break up your pipe at the points where you need to get the return code to work with it.
 
Old 01-02-2013, 08:47 PM   #3
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467
Blog Entries: 60

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by TobiSGD View Post
I don't really see why you want to use a pipe here. A pipe is used to pass output of a program to another program. If the return code is all you need there is no need for a pipe at all, just break up your pipe at the points where you need to get the return code to work with it.
I'm interested in both (standard) output and return value. It difficult to give any concrete example, because it is still nebulous in my own head. But basically what I'm interested in is a way to create a pipe, with real flowing data, that behaves differently depending on the return codes of commands in the pipe. One application might be a "failing" pipe with the following behavior: if all the commands in the pipe succeed, the final (standard) output of the pipe is the stdout of the last command. But if one of the commands fails, then the output of the whole pipe is the output of the last command that failed. Say, we have a wrapper command that makes this possible, called PF ("possibly fail")

PF parse "myfile" | PF refmtresults | PF updatedatabase | emailoutputto "admin@example.com"

Anyway, that is the sort of thing I'm thinking of. Maybe a "failing" pipe isn't really necessary, being as there is a division between stderr and stdout (not sure). But I imagine there might be other possible applications as well.
 
Old 01-03-2013, 02:21 AM   #4
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,752

Rep: Reputation: 463Reputation: 463Reputation: 463Reputation: 463Reputation: 463
PIPE_STATUS is what you want to look at.
 
Old 01-03-2013, 03:59 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,713

Rep: Reputation: 488Reputation: 488Reputation: 488Reputation: 488Reputation: 488
I have a similar question. Say I have a command like this:

Code:
make all 2>&1 | tee log.make.all
echo $?
The $? will be the return status of tee but it'd be better if it were that of make.
 
Old 01-03-2013, 05:36 AM   #6
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 651

Rep: Reputation: 269Reputation: 269Reputation: 269
Actually, I think it's PIPESTATUS (without the underscore).

example:

Code:
$ true | false | true
$ echo ${PIPESTATUS[@]}
0 1 0
 
2 members found this post helpful.
Old 01-03-2013, 05:53 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,713

Rep: Reputation: 488Reputation: 488Reputation: 488Reputation: 488Reputation: 488
Wow, thank you!
 
Old 01-04-2013, 03:28 AM   #8
hydraMax
Member
 
Registered: Jul 2010
Location: Skynet
Distribution: Debian + Emacs
Posts: 467
Blog Entries: 60

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by gnashley View Post
PIPE_STATUS is what you want to look at.
I think that PIPESTATUS does not work for what I wish to accomplish, because it suffers from the same issue as $?; i.e., it gives status information on the /last pipeline completed/, not the current pipeline. E.g.:

Code:
$ true | false | true
false | echo ${PIPESTATUS[@]}
0 1 0
What I am looking for is a way to pass return values down a pipeline.
 
Old 01-04-2013, 07:10 AM   #9
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 651

Rep: Reputation: 269Reputation: 269Reputation: 269
Quote:
Originally Posted by hydraMax View Post
I think that PIPESTATUS does not work for what I wish to accomplish, because it suffers from the same issue as $?; i.e., it gives status information on the /last pipeline completed/, not the current pipeline.
No, it won't work for you. The piped commands are executed in subshells, so they can not be aware of each other's exit codes.

Quote:
Originally Posted by hydraMax
But if one of the commands fails, then the output of the whole pipe is the output of the last command that failed.
"Last command that failed"? What's that? The processes are not run one after another. They all run simultaneously. The fact that their stdin and stdout file descriptors are redirected in a certain way does not make one process depend on the others. The commands in a pipe are sent to subshells regardless of what they do. It's up to each of these subshells to handle executing of the command they were given. None of these subshells knows anything about any of the others. It just gets input from somewhere and writes output somewhere.

The subshell then exits and sends its exit status to the parent shell. Only after all of the subshells exit, the $? and $PIPESTATUS are set.
If you have something like

Code:
grep foo file | grep bar | grep baz
By the time grep bar returns non-zero exit status, it is already too late to decide you want to print its output on screen instead of the output of grep baz.

You could possibly just echo the status code

Code:
(foo && echo $?) | bar
but I don't think it would be very useful. If you think you need to know the exit status of a piped command on the other side of the pipe, your program is probably poorly designed.

Last edited by millgates; 01-04-2013 at 07:14 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to pass pipe output to file command nickleus Linux - General 6 06-19-2008 06:18 AM
pass a string to a named pipe sahel Programming 1 01-05-2006 07:52 PM
binutils 1 pass :: broken pipe (?) jayprakash Linux From Scratch 2 02-14-2005 05:21 PM
Cannot pass and return a character array Linh Programming 1 06-12-2003 04:17 PM


All times are GMT -5. The time now is 04:17 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration