how to redirect stdout and stderr to file AND console

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'.
LVL 3
jlsjlsAsked:
Who is Participating?
 
evilrixConnect With a Mentor Senior Software Engineer (Avast)Commented:
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
 
omarfaridCommented:
Hi,

Try:

command 2> /dir/file.err | tee /dir/file.out > /dev/console ; cat /dir/file.err > /dev/console
0
 
evilrixSenior Software Engineer (Avast)Commented:
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
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
evilrixSenior Software Engineer (Avast)Commented:
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
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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
 
evilrixSenior Software Engineer (Avast)Commented:
...also, it will cause you a problem if you are wanting to append to the output files rather than over-write them
0
 
omarfaridCommented:
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
 
omarfaridCommented:
Hi,

You can always replace > with >>
0
 
evilrixSenior Software Engineer (Avast)Commented:
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
 
omarfaridCommented:
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
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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
 
omarfaridCommented:
Hi,

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

Try to make things simple :)

0
 
evilrixSenior Software Engineer (Avast)Commented:
>> Try to make things simple
Simple and correct are two different things!
0
 
omarfaridCommented:
Hi,

What are you trying to prove?

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

0
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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
 
jlsjlsAuthor Commented:
thanks for your reactions so far, I will investigate your solutions (try to understand and test on my machine).
I'll be b..
0
 
omarfaridCommented:
Hi,

Thank you jlsjls. Be sure that we both want to provide the best solution to you
0
 
jlsjlsAuthor Commented:
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
 
evilrixSenior Software Engineer (Avast)Commented:
>> ./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
 
omarfaridCommented:
Hi,

this is somthing you can do by:

- either running the job / script as root

- OR

chmod +w /dev/console
0
 
evilrixSenior Software Engineer (Avast)Commented:
>>- 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
 
omarfaridCommented:
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
 
jlsjlsAuthor Commented:
I've tested solution of evilrix within bash and it works fine.
Thanks omarfarid and evilrix for your input.
0
 
evilrixSenior Software Engineer (Avast)Commented:
Very welcome
0
All Courses

From novice to tech pro — start learning today.