LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices



Reply
 
Search this Thread
Old 02-25-2013, 10:42 PM   #1
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora
Posts: 2,563

Rep: Reputation: 475Reputation: 475Reputation: 475Reputation: 475Reputation: 475
bash stderr and stdout question


i was reading one of LQ members links about basic bash scripting and stopped at this section. what is the difference between the following:

Quote:
3.4 Sample: stdout 2 stderr

This will cause the stderr ouput of a program to be written to the same filedescriptor than stdout.

grep da * 1>&2

Here, the stdout portion of the command is sent to stderr, you may notice that in differen ways.
3.5 Sample: stderr 2 stdout

This will cause the stderr ouput of a program to be written to the same filedescriptor than stdout.

grep * 2>&1
this is from the following link:

http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html

looks to me that both do basically the same thing. they both send stderr and stdout to a file. is that correct?

sorry this is something in never really wrapped my head around when the guy who showed me what little i know about bash scripting talked about this portion.

thanks in advance to helping.
 
Old 02-25-2013, 11:22 PM   #2
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,310

Rep: Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039Reputation: 2039
Basically they have the same effect
Code:
# each *nix process is automatically created with 3 channels
# 0 = stdin
# 1 = stdout
# 2=  stderr

# write stdout to log; default assumes chan 1 if not specified
prog 1> prog.log
prog >prog.log

# send chan 2/stderr to same place ( &1 = addr of stdout)
prog >prog.log 2>&1
http://rute.2038bug.com/index.html.gz
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/
 
1 members found this post helpful.
Old 02-26-2013, 12:33 AM   #3
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,153

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Well, except 1>&2 directs stdout to stderr, and 2>&1 directs strerr to stdout. Typically, stderr and stdout are both the console, so the practical effect is that all the output goes to the console. There are, however, cases where, for example, strout is intended to be piped into some file, or where stderr is intended to be a log file, where which is the source and destination could, conceivably, make a difference.

There is another idiom that I find useful: &>/dev/null which sends everything into the bit bucket. Here's an example of a script I have in my bin directory:
Code:
$ cat ~/bin/Kate
#!/bin/bash
sudo /bin/kate "$*" &>/dev/null &
code=$?
disown
exit ${code}
(That script starts the kate editor from the command line as a separate process with "root" access, and doesn't "mess up" the terminal output with status and warning messages. Useful when, for example, I want to change something in, say, /etc/fstab and test the changes in the terminal before rebooting.)
 
1 members found this post helpful.
Old 02-26-2013, 08:44 AM   #4
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora
Posts: 2,563

Original Poster
Rep: Reputation: 475Reputation: 475Reputation: 475Reputation: 475Reputation: 475
thank you both. that helps clear things up a bit.
 
Old 02-26-2013, 09:42 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950
"&>" is however a bash-specific shortcut (redirect fd1 and fd2 together), and not generally recommended. The standard, portable redirection is this:

Code:
command >/dev/null 2>&1

I will say that the concept of file descriptors does take some time to learn properly. The main points that helped me to understand what was happening were these:


1) Every command has three file descriptors automatically set up; stdin (fd0, the input into the command), stdout (fd1, the main text output), and stderr (fd2, error messages or other text that's intended for display only, and doesn't "mix" with stdout). These are the numbers on the left side of the redirection arrow (no number = fd0 or fd1, depending on the arrow direction). These cannot be changed; they can only be connected to a different output (or input, for fd0).

2) The right side of the arrow can be either a file name or "&n". "&n", in this context basically means "the same target location that file descriptor n is currently set to". i.e. what it does not mean is "send it to fdn".

3) Any pre-existing file descriptors are first inherited from the parent shell, and then the ones on the command line are set from left to right. Any redirection using "&n" will naturally depend on what got set before it.


Thus "command >/dev/null 2>&1", translated into regular speech, is "send the command's stdout content to /dev/null, then send it's stderr content to the same place that stdout is currently pointing (which is now /dev/null)". Both stdout and stderr end up going into the bitbucket.

"command 2>&1 >/dev/null", on the other hand, means "send the command's stderr content to the same place that stdout is currently pointing (the screen, by default), then send it's stdout content to /dev/null. So the command's stderr messages end up going to the screen (but now as stdout content, so it will also pass through pipes, etc), and the original stdout content gets thrown away.


See here for the best explanation of file descriptors I've yet read:
http://www.catonmat.net/blog/bash-on...ed-part-three/
 
2 members found this post helpful.
Old 02-26-2013, 12:14 PM   #6
lleb
Senior Member
 
Registered: Dec 2005
Location: Florida
Distribution: CentOS/Fedora
Posts: 2,563

Original Poster
Rep: Reputation: 475Reputation: 475Reputation: 475Reputation: 475Reputation: 475
Quote:
Originally Posted by David the H. View Post
"&>" is however a bash-specific shortcut (redirect fd1 and fd2 together), and not generally recommended. The standard, portable redirection is this:

Code:
command >/dev/null 2>&1
"command 2>&1 >/dev/null", on the other hand, means "send the command's stderr content to the same place that stdout is currently pointing (the screen, by default), then send it's stdout content to /dev/null. So the command's stderr messages end up going to the screen (but now as stdout content, so it will also pass through pipes, etc), and the original stdout content gets thrown away.
thank you for the more detailed explanation, but i have a fast question about this last bit...

with 2>&1 >/dev/null you are saying that the stderr will go to the screen by default, but the stdout will go straight to the bitbucket? would not both goto the screen?
 
Old 03-02-2013, 10:24 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950Reputation: 1950
No. Read what I wrote before carefully. "&1" represents the target of fd1, not fd1 itself. Perhaps it would help if you thought of "&n" as kind of like a variable, which holds the value of the target of fdn.


So start with the initial default configuration of "fd1 --> screen(stdout)", and "fd2 --> screen(stderr)". They both print to the screen by default, but are otherwise treated as separate data blocks. Only the stdout data will pass through a pipe, for example.

"2>&1" changes the target of fd2 from screen(stderr) to screen(stdout), the current target of fd1. Remember, it's not sending stderr directly to stdout.

Then ">/dev/null" sets fd1 to the filename /dev/null. fd2 is still pointing to screen(stdout).

So the result is "fd1 --> /dev/null", and "fd2 --> screen(stdout)".

Last edited by David the H.; 03-02-2013 at 10:27 AM. Reason: bit 'o formatting
 
  


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
[SOLVED] Bash: Stderr & Stdout 2 file Ztcoracat Linux - General 9 11-18-2012 10:23 AM
bash output stderr to 2 files and stdout vascot Linux - Software 1 04-05-2011 09:04 AM
Perl stderr&stdout redirect question Fredde87 Programming 5 03-26-2009 05:43 AM
bash logging stdout plus stderr freeindy Programming 6 01-29-2009 10:16 AM
shell short question(stdout, stderr) blackzone Programming 4 11-11-2004 10:01 AM


All times are GMT -5. The time now is 05:56 AM.

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