Solved

how to redirect stdout and stderr to file AND console

Posted on 2007-11-27
24
5,235 Views
Last Modified: 2013-12-26
I want to redirect stdout and stderr of a shell UNIX script to 2 different files and also the stdout and stderr-messages must appear on the console. How should I do this?
stdout -> file.out
stderr -> file.err
also post this information to the console
don't succeed doing this using command 'tee'.
0
Comment
Question by:jlsjls
[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
  • 12
  • 9
  • 3
24 Comments
 
LVL 40

Expert Comment

by:omarfarid
ID: 20357223
Hi,

Try:

command 2> /dir/file.err | tee /dir/file.out > /dev/console ; cat /dir/file.err > /dev/console
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357230
There the name of your script is SCRIPTNAME: -

(((./SCRIPTNAME | tee stdout.txt) 3>&1 1>&2 2>&3|tee stderr.txt) 3>&1 1>&2 2>&3) 2>&1

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357253
To make the final output stage go to the console use...
 (((./x.pl | tee stdout.txt) 3>&1 1>&2 2>&3|tee stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/console 2>&1

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 40

Expert Comment

by:evilrix
ID: 20357337
>> command 2> /dir/file.err | tee /dir/file.out > /dev/console ; cat /dir/file.err > /dev/console

NB. This doesn't quite do the same thing as it cats file.err to the console as a second command, so the redirection for stderr to the console and file isn't atomic. Were the file altered in between writing it and cat'ing it to console the output wouldn't match the original output from the script. This might be fine for a one off task but if this is to monitor automated processes you really should use atomic redirection to ensure consistency between original output and what's written to the console.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357348
...also, it will cause you a problem if you are wanting to append to the output files rather than over-write them
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20357362
Hi,

evilrix:

you are right, but try:

command 2> /dir/file.err | tee /dir/file.out > /dev/console &
cat /dir/file.err > /dev/console &

0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20357365
Hi,

You can always replace > with >>
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357713
You miss my point. The action is still not atomic as you are sending /dir/file.err to the console NOT the stderr output from the original script. If file.err is an ever growing log file you will cat the whole of this file to the console -- this is what I meant when I stated it'll cause you problems if you want to append (I do know what > and >> do !!!). Consider, run the command twice with append not overwrite...

command 2>> /dir/file.err | tee -a /dir/file.out > /dev/console ; cat /dir/file.err > /dev/console
command 2>> /dir/file.err | tee -a /dir/file.out > /dev/console ; cat /dir/file.err > /dev/console

The 2nd command will also output the original contents of file.err to the console as it is just appended to.

Now try this...

(((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/console 2>&1
(((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/console 2>&1

You will get only one lot of output sent to the console each time.

Using & rather than ; (to background each separate part) does nothing to solve this issue!

Example: -
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
stderr
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
stderr
stderr
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
stderr
stderr
stderr
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
stderr
stderr
stderr
stderr
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
stderr
stderr
stderr
stderr
stderr
rwc-lnx-box:~/tmp$ ./x.pl 2>> file.err | tee -a file.out > /dev/stdout ; cat file.err > /dev/stdout
stdout
stderr
stderr
stderr
stderr
stderr
stderr
stderr
 
 
Vs.
 
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stdout
stderr
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout
rwc-lnx-box:~/tmp$ (((./x.pl | tee -a stdout.txt) 3>&1 1>&2 2>&3|tee -a stderr.txt) 3>&1 1>&2 2>&3) 1>/dev/stdout 2>&1
stderr
stdout

Open in new window

0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20357766
Hi,

evilrix:

Thank you for your explanation. I think what I posted will do the job for the time being. If the end user is welling to run the same command / process twice as you just described, then we can think of changing it.

Thanks again.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357817
>> I think what I posted will do the job for the time being
Well yes, or the OP could just use what I posted, which is the correct way to do this :)
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20357835
Hi,

Why don't you wait till jlsjls decides which way to go :)

Try to make things simple :)

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357912
>> Try to make things simple
Simple and correct are two different things!
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20357928
Hi,

What are you trying to prove?

I said leave it to the owner, you made your point clear.

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20357955
>> What are you trying to prove?
You seem to be implying the OP should choose your suggestion because it is simple -- It is important to realize the potential implications of choosing a 'simple' solution that isn't wholly correct!
0
 
LVL 3

Author Comment

by:jlsjls
ID: 20358686
thanks for your reactions so far, I will investigate your solutions (try to understand and test on my machine).
I'll be b..
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20358750
Hi,

Thank you jlsjls. Be sure that we both want to provide the best solution to you
0
 
LVL 3

Author Comment

by:jlsjls
ID: 20364190
I've integrated the solution of evilrix in my scripts and I receive following error :
./job_ksh_test[9]: syntax error at line 8 : `(' unexpected
-> how to solve it??

(((rm /opt/vtom/scripts/jurgen.file | tee /opt/vtom/scripts/stdout.txt) 3>&1 1>&2
 2>&3|tee /opt/vtom/scripts/stderr.txt) 3>&1 1>&2 2>&3) 2>&1
remark : file 'jurgen.file' doesn't exist so generate stderr

BTW.  when using solution of omarfarid : no access to /dev/console -> only root has access
#!/bin/ksh
echo "-----------------------------------"
echo "  Exemple de Script Visual TOM"
echo "-----------------------------------"
(((rm /opt/vtom/scripts/jurgen.file | tee /opt/vtom/scripts/stdout.txt) 3>&1 1>&2 2>&3|tee /opt/vtom/scripts/stderr.txt) 3>&1 1>&2 2>&3) 2>&1

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20364255
>> ./job_ksh_test[9]: syntax error at line 8 : `(' unexpected
The syntax I provided was for the bash shell, it has not been tested on ksh.
http://www.gnu.org/software/bash/

>> BTW.  when using solution of omarfarid : no access to /dev/console -> only root has access
That is because only root can write to /dev/console so you'll need to be logged in as root

ls -l /dev/console
crw-------  1 root root 5, 1 2007-11-28 09:47 /dev/console


0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20364258
Hi,

this is somthing you can do by:

- either running the job / script as root

- OR

chmod +w /dev/console
0
 
LVL 40

Accepted Solution

by:
evilrix earned 250 total points
ID: 20364266
If you already have bash installed try this instead...
#!/bin/bash
echo "-----------------------------------"
echo "  Exemple de Script Visual TOM"
echo "-----------------------------------"
(((rm /opt/vtom/scripts/jurgen.file | tee /opt/vtom/scripts/stdout.txt) 3>&1 1>&2 2>&3|tee /opt/vtom/scripts/stderr.txt) 3>&1 1>&2 2>&3) 2>&1 

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 20364282
>>- OR chmod +w /dev/console

I would strongly recommend you do not play with the default permissions of your devices as this can introduce security issues! There is a reason /dev/console is root only, amongst other things this is to stop it being flooded by any old users script!
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20364301
Hi,

Yes, but if he is the only user or he knows what are the scripts running on the m/c , then it is ok.

Any way I prefer the first option of running the job / script as root.

0
 
LVL 3

Author Comment

by:jlsjls
ID: 20364514
I've tested solution of evilrix within bash and it works fine.
Thanks omarfarid and evilrix for your input.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 20364640
Very welcome
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Creating Labels and Frequency list style reports in SAS code 9 110
if loop in java 3 160
format the code in java 6 109
mapBully challenge 6 175
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
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.
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

740 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