Solved

how to redirect stdout and stderr to file AND console

Posted on 2007-11-27
24
5,204 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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

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…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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 demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

760 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

20 Experts available now in Live!

Get 1:1 Help Now