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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
03-19-2007, 03:58 PM
|
#1
|
|
LQ Newbie
Registered: Mar 2007
Location: switzerland
Distribution: redhat-fedora,suse,various
Posts: 3
Rep:
|
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
|
|
|
|
03-19-2007, 04:09 PM
|
#2
|
|
Member
Registered: Dec 2003
Location: Toronto, Canada
Distribution: Mandriva, Ubuntu, LFS, gNewSense
Posts: 221
Rep:
|
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.
|
|
|
|
03-20-2007, 01:07 AM
|
#3
|
|
LQ Newbie
Registered: Mar 2007
Location: switzerland
Distribution: redhat-fedora,suse,various
Posts: 3
Original Poster
Rep:
|
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
|
|
|
|
03-20-2007, 03:58 AM
|
#4
|
|
LQ Newbie
Registered: Mar 2007
Location: switzerland
Distribution: redhat-fedora,suse,various
Posts: 3
Original Poster
Rep:
|
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...!
|
|
|
|
03-24-2007, 08:04 PM
|
#5
|
|
Senior Member
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 2,962
Rep: 
|
Code:
#!/bin/bash
echo "NORMAL!" > /proc/self/fd/1
echo "ERROR!" > /proc/self/fd/2
ta0kira
|
|
|
|
03-24-2007, 08:09 PM
|
#6
|
|
Senior Member
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 2,962
Rep: 
|
Wait, maybe I'm misunderstanding. Will this work?
Code:
( ./your-script > ./stdout_pipe ) 2> ./stderr_pipe
ta0kira
|
|
|
|
09-05-2012, 12:57 PM
|
#7
|
|
LQ Newbie
Registered: Sep 2012
Posts: 2
Rep: 
|
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.
|
09-07-2012, 01:39 AM
|
#8
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,568
|
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?
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 07:06 AM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|