?
Solved

how to redirect standard error and output from a shell script to a file

Posted on 2005-03-15
17
Medium Priority
?
9,483 Views
Last Modified: 2013-12-26
Hi all,
    by doing this:

script.sh 2>>output.txt

I am able to run the script and send the errors if any to output.txt but how can I send both the output and errors to output.txt by running the script only once.

Also how I can send errors+output to both screen and output.txt by running the script only once.

Thanks in advance
chintaps
0
Comment
Question by:chintaps
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
  • 2
17 Comments
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13546325
depends on the shell you are using...

for Bourne Shell, KSH and Bash:

# redirect both to same output file
script.sh >output.txt 2>&1

# redirect separately
script.sh >output.txt 2> error.txt

# redirect stdout to null and save error
script.sh >/dev/null 2> error.txt

0
 
LVL 11

Assisted Solution

by:cjjclifford
cjjclifford earned 1000 total points
ID: 13546335
sorry, missed the last bit (to screen and file)

Use "tee"

script.sh 2>&1 | tee output.txt

0
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13546350

with tee, the -a flag tells it to append rather than (Default) of clobber.
0
Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

 
LVL 16

Accepted Solution

by:
manav_mathur earned 1000 total points
ID: 13546624
cjjclifford,

all the commands specified above will clobber the target file

script.sh >> output.txt 2>&1  ##will append all STDOUT/STDERR to output.txt
script.sh 2>&1 | tee -a output.txt ##will make all STDERR?STDOUT appear on screen and append to output.txtx

Manav
0
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13546695
manav_manthur, there was no mention in the question of not clobbering, but yes ">>" rather than ">" will append (I mentioned the "tee -a" option myself).

0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 13546734
The question involved a statement like

<quote>
script.sh 2>>output.txt
</quote>

Just wanted to bring to notice that the solution above, unlike the command posted in the question itself, will clobber the files. If the author has no problems with this, its his call.

Cheers
Manav


0
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13546846
fair enough...

actually, looking at the quote from the question it looks like its a CSH shell - is this correct author?



0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 13546869
> CSH shell
Isnt the format same for ksh,bash (any other shell) ??

Manav
0
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13547020
nope, AFAIK CSH is broken.... (in particular how it handles file descriptors is broken... a quick google on "csh considered harmful" gives http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/

a quick test highlights that the same format doesn't work:

% python -c "import sys; sys.stderr.write( 'hello ' ); print 'world'" >> /tmp/test1.txt 2>&1
csh: Ambiguous output redirect.

whereas in Bash:

$ python -c "import sys; sys.stderr.write( 'hello ' ); print 'world'" 2>&1 | tee /tmp/test3.txt
hello world
[]$ cat /tmp/test3.txt
hello world
[]$

0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 13547068
beg your pardon......Im not able to understand what you are trying to say here.......
<quote>
by doing this:

script.sh 2>>output.txt

I am *able* to run the script ....
</quote>

a '>>' works fine on bash, ksh but not on csh(as you've just shown). And the author says that he *is* able to run th command that uses this form of redirection, he should not be on csh....or am I missing something here??

Manav
0
 

Author Comment

by:chintaps
ID: 13547132
its a Bourne shell! thanks for the answers guys!
Both these work:
script.sh >> output.txt 2>&1  ##will append all STDOUT/STDERR to output.txt
script.sh 2>&1 | tee -a output.txt ##will make all STDERR?STDOUT appear on screen and append to output.txtx

the difference is the return code from both! While 1 gives the same code(error if error in script) as a return code 2 actually gives it as true no matter what. So if I do a
if [ $? = 0 ];
after this line its a success always!!! is there a way around this?

Thanks
chintaps
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 13547189
The second command will give the return code of the tee command, not your script.....

Manav



0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 13547229
an indirect method may be to touch a file if this succeeds, and check for the existence of the file...(thats what occurs to my bleak mind)

script.sh 2>&1 && touch /tmp/file1 | tee -a output.txt
if [ -a /tmp/file1 ]; then
#script.sh succeeded, do something to celebrate!!
rm /tmp/file1
0
 
LVL 16

Expert Comment

by:manav_mathur
ID: 13547235
or should it be
{script.sh 2>&1 && touch /tmp/file1} | tee -a output.txt
0
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13547477
There's an example of how to get return values from programs earlier in the pipe than the last one, on that URL regarding CSH being harmful...

to quote:
Consider the pipeline:

    A | B | C

You want to know the status of C, well, that's easy: it's in $?, or
$status in csh.  But if you want it from A, you're out of luck -- if
you're in the csh, that is.  In the Bourne shell, you can get it, although
doing so is a bit tricky.  Here's something I had to do where I ran dd's
stderr into a grep -v pipe to get rid of the records in/out noise, but had
to return the dd's exit status, not the grep's:

    device=/dev/rmt8
    dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
    exec 3>&1
    status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4) |
                egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1`
    exit $status;

--- End Quote

Making sense of this is a little painful...
for our simple example...
(I don't fully follow what is going on, but I got it to work relatively easily....

exec 3>&1
status=$( ((./script.sh 2>&1 1>&3 3>&- 4>&-; echo $?>&4) | tee /tmp/test.txt 1>&2 3>&- 4>&- ) 4>&1 )
echo $status

The return code gets extracted correctly, but the output mightn't be fully correct... too many angle brackets, and amersands!!!! I'm off home!!


0
 

Author Comment

by:chintaps
ID: 13547967
This works fine! thanks guys.
0
 
LVL 11

Expert Comment

by:cjjclifford
ID: 13553015
:-)
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question