Solved

how to redirect stdout and stderr to file AND console

Posted on 2007-11-27
24
5,208 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
  • 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Show shut-down message as Windows 8 shuts down. 9 85
Named range not carried over 10 62
lucky13 challenge 11 122
how to use laptop or pad camera in vb.net windows application 2 54
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
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.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

920 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now