[SOLVED] stdout, stderr and redirection -- what is the correct order or format ?
Linux - NewbieThis 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
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.
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.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
stdout, stderr and redirection -- what is the correct order or format ?
Hi all,
Been reading on stdin, stdout and stderr and encounter 2 questions, hope gurus here can advise.
0 = stdin
1 = stdout
2 = stderr
Code:
Sun Dec 21 03:53:42 SGT 2014 > cat test5.sh
#!/bin/bash
echo "Please enter value for name :"
read name
echo "Your name is $name."
echo "Next echo will be a syntax error"
ehco
Code:
Sun Dec 21 03:53:46 SGT 2014 > test5.sh 1> output.txt 2> error.txt
Noob
Sun Dec 21 03:54:56 SGT 2014 > cat output.txt
Please enter value for name :
Your name is Noob.
Next echo will be a syntax error
Sun Dec 21 03:55:23 SGT 2014 > cat error.txt
/home/alan/scripts/test5.sh: line 8: ehco: command not found
Sun Dec 21 03:55:26 SGT 2014 >
Which so far all is good and the correct way to output everything including error to a single file is
Code:
Sun Dec 21 03:59:14 SGT 2014 > test5.sh > output.txt 2>&1
Q1) How is a command being interpreted in linux , the sequence in which it is interpreted ? from left to right ? right to left ?
Shouldn't it be
Code:
test5.sh 2>&1 1>output.txt
or
test5.sh 2>&1>output.txt ?
It's interpreted left to right, with each action redirecting to where the target was at that moment.
Code:
test5.sh >output.txt 2>&1
stdout is redirected to output.txt, then stderr is redirected to where stdout is now going (i.e., the file).
Code:
test5.sh 2>&1 1>output.txt
stderr is redirected to where stdout is currently going (probably the terminal, or else to the place where the whole script's stdout was redirected), then stdout is redirected to output.txt.
If there is a pipeline involved, you have to realize that the shell sets up the pipeline redirections before the redirections in the individual commands.
Code:
test5.sh 2>&1 1>output.txt | cat
stderr will get redirected to the cat command's stdin, then stdout will be redirected to output.txt.
It's interpreted left to right, with each action redirecting to where the target was at that moment.
Code:
test5.sh >output.txt 2>&1
stdout is redirected to output.txt, then stderr is redirected to where stdout is now going (i.e., the file).
Code:
test5.sh 2>&1 1>output.txt
stderr is redirected to where stdout is currently going (probably the terminal, or else to the place where the whole script's stdout was redirected), then stdout is redirected to output.txt.
If there is a pipeline involved, you have to realize that the shell sets up the pipeline redirections before the redirections in the individual commands.
Code:
test5.sh 2>&1 1>output.txt | cat
stderr will get redirected to the cat command's stdin, then stdout will be redirected to output.txt.
Hi rknichols,
Sorry for the late reply. It will be good if you are still on this thread though....
I tried your examples but I still unable to grasp the idea. If the execution is from left to right meaning
test5.sh > output.txt 2>&1
T1) Execute the script test5.sh
T2) Redirect all output to output.txt
T3) Redirect all error to output (which is now pointed at output.txt)
Then in that case, for my script below,
Code:
#!/bin/bash
echo "1"
echo "2"
echo "Next echo will be a syntax error"
ehco
echo "Ok now it is working"
the results in output.txt should be
Quote:
1
2
Ok now it is working /home/alan/scripts/test5.sh: line 7: ehco: command not found
as the error is define to be redirect to &1 at T3 isn't it ?
But now it is showing in the right order
Quote:
1
2 /home/alan/scripts/test5.sh: line 7: ehco: command not found
Ok now it is working
Why ? Is it because the whole statement is evaluated 1st before the execution ?
================================================================================================
Also, if the whole statement is evaluated (from left to right) before the execution of the script, then why is the error printed out on the screen but not capture in output.txt for this command below ->
Code:
[alan@racnode1 scripts]$ test5.sh 2>&1 1>output.txt
/home/alan/scripts/test5.sh: line 7: ehco: command not found
I tried your examples but I still unable to grasp the idea. If the execution is from left to right meaning
test5.sh > output.txt 2>&1
T1) Execute the script test5.sh
T2) Redirect all output to output.txt
T3) Redirect all error to output (which is now pointed at output.txt)
No. The "left to right" evaluation by the shell applies only to the redirections, not to the entire command line. The redirections are always set up before execution of the command begins. The redirections merely define where the output is going. There is no implication of collecting all of stdout and stderr separately and then sending the two collections in sequence to the destination. The time sequence is:
T1) Set up stdout to be sent to file output.txt,
T2) Set up stderr to be sent to the place where stdout is now directed (i.e., the file),
T3) Execute the command.
Quote:
Also, if the whole statement is evaluated (from left to right) before the execution of the script, then why is the error printed out on the screen but not capture in output.txt for this command below ->
Code:
[alan@racnode1 scripts]$ test5.sh 2>&1 1>output.txt
/home/alan/scripts/test5.sh: line 7: ehco: command not found
The sequence of actions here is:
T1) Set up stderr to go to the place where stdout is now going (probably the terminal),
T2) Set up stdout to go to file output.txt (this does not affect the redirection already set up for stderr),
T3) Execute the command.
For the case where that command line was typed at the terminal, stdout and stderr were very likely already going to the terminal, so step T1 is basically a no-op. But, consider the following:
Code:
$ test5.sh 2>&1 1>output.txt | mail someuser
Now, stdout was originally going to the pipeline, so the sequence of redirections now results is stderr being sent to the mail program and stdout going to file output.txt.
It's really not all that complicated, but you seem to be locked into an initial misconception that you've got to lose somehow. It's a bit like a co-worker of mine from long ago who always had to struggle against thinking, "You open a file for input when you want to put something in it, right?" (At least he had no problem remembering that was wrong.)
BTW, the reason rknichols explaination is correct is that the shell sets up the first command for the redirection, then sets the first command for a pipe (which is a new stdout connected to the pipe), then it sets up stdin to receive the data from the pipe, then executes the last program (which has stdout and stderr redirected.
No. The "left to right" evaluation by the shell applies only to the redirections, not to the entire command line. The redirections are always set up before execution of the command begins. The redirections merely define where the output is going. There is no implication of collecting all of stdout and stderr separately and then sending the two collections in sequence to the destination. The time sequence is:
T1) Set up stdout to be sent to file output.txt,
T2) Set up stderr to be sent to the place where stdout is now directed (i.e., the file),
T3) Execute the command.
The sequence of actions here is:
T1) Set up stderr to go to the place where stdout is now going (probably the terminal),
T2) Set up stdout to go to file output.txt (this does not affect the redirection already set up for stderr),
T3) Execute the command.
For the case where that command line was typed at the terminal, stdout and stderr were very likely already going to the terminal, so step T1 is basically a no-op. But, consider the following:
Code:
$ test5.sh 2>&1 1>output.txt | mail someuser
Now, stdout was originally going to the pipeline, so the sequence of redirections now results is stderr being sent to the mail program and stdout going to file output.txt.
It's really not all that complicated, but you seem to be locked into an initial misconception that you've got to lose somehow. It's a bit like a co-worker of mine from long ago who always had to struggle against thinking, "You open a file for input when you want to put something in it, right?" (At least he had no problem remembering that was wrong.)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.