LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
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 03-19-2007, 03:58 PM   #1
ask4info
LQ Newbie
 
Registered: Mar 2007
Location: switzerland
Distribution: redhat-fedora,suse,various
Posts: 3

Rep: Reputation: 0
separte pipe for stderr and stout in a bash script


hi all

what's the best way to output the stderr and stdout of a shell command thru different pipes?
I want to process the stderr different from stout, generated by a command. How to combine both and still have the same output descriptors? In other words, how
to combine ("a one liner"!) the two commands:

command 2>&1 | .. pipe 1 .. -> sterr (&2)
command | .. pipe 2 ... -> stdout (&1)

any ideas?

thanks
 
Old 03-19-2007, 04:09 PM   #2
cfaj
Member
 
Registered: Dec 2003
Location: Toronto, Canada
Distribution: Mint, Mandriva
Posts: 221

Rep: Reputation: 31
Quote:
Originally Posted by ask4info
hi all

what's the best way to output the stderr and stdout of a shell command thru different pipes?
I want to process the stderr different from stout, generated by a command. How to combine both and still have the same output descriptors? In other words, how
to combine ("a one liner"!) the two commands:

command 2>&1 | .. pipe 1 .. -> sterr (&2)
command | .. pipe 2 ... -> stdout (&1)

any ideas?
Use a named pipe. This is a very basic example:
Code:
q()
{
  echo 1_$RANDOM
  echo 2_$RANDOM >&2
}

mkfifo stdo
cat stdo &
q 2>stdo | cat
rm stdo
Or save stderr to a regular file and have your command read from that.


Last edited by cfaj; 03-19-2007 at 04:11 PM.
 
Old 03-20-2007, 01:07 AM   #3
ask4info
LQ Newbie
 
Registered: Mar 2007
Location: switzerland
Distribution: redhat-fedora,suse,various
Posts: 3

Original Poster
Rep: Reputation: 0
hi cfai

thanks for your sample.

thats what i did too however i was wondering wether there is a "smart" way to do it with e.g. the 'exec' command somehow. The sample below is now my final:

#!/bin/bash

q()
{
echo 1_stdout
echo 2_stderr >&2
}

p()
{
rm -fr /tmp/stdo
mkfifo /tmp/stdo
cat /tmp/stdo | sed 's|err|ERR|g' >&2 &
q 2>/tmp/stdo | sed 's|out|OUT|g'
rm -fr /tmp/stdo
}

echo -n "sterr: "
p 1>/dev/null
echo -n "stout: "
p 2>/dev/null

Note: what was missing was the redirection of the named pipe to &2

have a nice day
 
Old 03-20-2007, 03:58 AM   #4
ask4info
LQ Newbie
 
Registered: Mar 2007
Location: switzerland
Distribution: redhat-fedora,suse,various
Posts: 3

Original Poster
Rep: Reputation: 0
hi cfai

i just found out a better way using the designator swapping technic:

#!/bin/bash

cmd()
{
echo 1_stdout
echo 2_stderr 1>&2
}

out1() # different sub shell
{
( ( cmd | sed 's|out|OUT|g' ) 3>&1 1>&2 2>&3 | sed 's|err|ERR|g' ) 3>&1 1>&2 2>&3
# \----swap----/ |-> stout=stderr \----swap----/
}

out2() # current sub shell
{
{ { cmd | sed 's|out|OUT|g'; } 3>&1 1>&2 2>&3 | sed 's|err|ERR|g'; } 3>&1 1>&2 2>&3
# \----swap----/ |-> stout=stderr \----swap----/
}

echo -n "sterr: "
out1 1>/dev/null
echo -n "stout: "
out1 2>/dev/null


until next question...!
 
Old 03-24-2007, 08:04 PM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Code:
#!/bin/bash
echo "NORMAL!" > /proc/self/fd/1
echo "ERROR!" > /proc/self/fd/2
ta0kira
 
Old 03-24-2007, 08:09 PM   #6
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Wait, maybe I'm misunderstanding. Will this work?
Code:
( ./your-script > ./stdout_pipe ) 2> ./stderr_pipe
ta0kira
 
Old 09-05-2012, 12:57 PM   #7
i_am_sorry
LQ Newbie
 
Registered: Sep 2012
Posts: 2

Rep: Reputation: Disabled
I am sorry for necroing this thread, but I found it while searching for a very similar problem and in case someone else finds this after me I want to provide an even better answer.

First,
Code:
( cmd | sed 's|out|OUT|g' ) 3>&1 1>&2 2>&3 | sed 's|err|ERR|g'
is really all you need, the swapping at the end is superfluous, because nothing is done with it after the second sed and the descriptors get reset to their previous state automatically.

Now to the better solution:
Code:
cmd 1> >(sed 's|out|OUT|g') 2> >(sed 's|err|ERR|g')
It's that simple

As a little extra *g*, you can use this to play all files found under the current directory with mplayer without losing control (because /dev/stdin doesn't get redirected from /dev/null) and without using a pipe made by mkfifo:
Code:
(xargs -a /proc/self/fd/3 -0 mplayer -vo null -shuffle) 3< <(find -type f -print0)
my source: h++p://stupefydeveloper.blogspot.de/2008/10/bash-file-descriptors_20.html

I hope this necro was not too annoying and instead relevant and "timely" enough
 
1 members found this post helpful.
Old 09-07-2012, 01:39 AM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Reopening an old thread is usually ok as long as you're adding something new and useful to the original conversation, and particularly if you also make it clear that you are re-opening it. You've done both, so I say good work.

I just want to point out clearly that what you've posted uses the bash-specific process substitution, and is therefore not portable across shells, unlike the standardized redirections and fifos. But they are very convenient.

As the above link points out, ksh appears to also have process substitution built in, but apparently it can't be combined with shell redirections in the way shown above. Perhaps with dedicated file descriptors?
 
  


Reply



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
Shell script pipe input - bash mostly laikos Programming 4 11-09-2008 05:14 PM
Shell script - stdout & stderr to terminal and file jantman Linux - Software 1 12-07-2006 04:34 PM
bash stderr redirect question code-breaker Linux - Software 1 08-06-2006 04:44 AM
Redirecting error messages to stderr and file in Bash lowpro2k3 Programming 1 04-14-2005 06:47 PM
Read the output from a pipe with bash ? fluppi Linux - Software 3 01-13-2004 12:59 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:07 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration