File descriptors, redirecting output, and stdout


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting File descriptors, redirecting output, and stdout
# 1  
Old 07-23-2012
File descriptors, redirecting output, and stdout

Hello all. I've been lurking here for a year or two and finally decided to post.

I need some assistance with file descriptors, stdout, and redirecting output. I've searched through a number of very helpful threads here (unfortunately I can't link to any of them yet due to my low post count...), and I've done a fair amount of experimenting, but I haven't been able to come up with a solution. (I really tried to do my own legwork before asking for help.)

I'm writing a ksh script that opens up two file descriptors, one for the "regular" log file (exec 3> myfile) and one specifically for an error log file (exec 4> my_error_file).

I want the output to be directed to specific files, and to make this mandatory and beyond user control. However, I would also like to have the script output to the terminal as it executes.

I can redirect to my file descriptors just fine; I can't figure out how to simultaneously redirect to the terminal, though. I have unsuccessfully tried to use tee and I've tried redirecting my output in various ways, but I'm missing something fundamental. I would be very appreciative if anybody could offer any advice!

Here are the relevant code snippets and some psuedocode of what I'm doing and what I've tried thus far:

Code:
#!/usr/bin/ksh
LOG_FILE=/home/mydir/regular_log_file.log
LOG_ERROR_FILE=/home/mydir/error_log_file.log
 
exec 3> $LOG_ERROR_FILE # send this to regular_log_file.log. Non-error information messages get written here
exec 4> $LOG_ERROR_FILE # send this to error_log_file.log. If it blows up, it gets written here
 
# usage() function
usage(){ 
print " There's lots of print commands here that show how to use this script. I want these to display to both the screen and the relevant log file. 
I get it to the log file just fine by using 'usage 1>&4', so I don't have to specify where the file goes when I call print"
}
 
# send_email() function
# send email if the script fails
send_email(){ 
cat $ERROR_LOG_FILE | mailx ... ... ...
}

... and later in the script ...

Code:
# attempt to touch tarfile to see whether we can write
# the TARFILE_LOCATION and TARFILE variables get set properly in code I didn't include; trust me
touch ${TARFILE_LOCATION}/${TARFILE} > /dev/null
if [[ $? != 0 ]]; then
print -u4 " "
print -u4 "ERROR: Unable to write tarfile to $TARFILE_LOCATION."
print -u4 " Script cannot recover from this error. Exiting..."
send_email
fi


So, as you can see, all of my error output gets processed through "print -u4" commands, removing the need for excessive amounts of > and >> redirects. The script looks tidy, I don't have to carefully troubleshoot 700 lines to make sure that I didn't accidentally > when I meant to >>, and life is good.

Debugging is a pain, though. I have to go dig up the log files each and every time in order to see how the script behaved. I would like to be able to continue to call "print -u4 text" but also be able to see that output in stdout, so when I (or other people) use the script, it appears to actually do something.

I know the script is doing something, but a lot of people will use this, see a blank line and "hung" cursor, and panic...

Any help would be much appreciated! Thank you!
Moderator's Comments:
Mod Comment Code tags for code, please.

Last edited by Michael_K; 07-23-2012 at 03:02 PM..
# 2  
Old 07-23-2012
Instead of redirecting to 3 and 4 and using 'print -u4', you could've redirected stdout and stderr themselves. with 'exec 1>' and 'exec 2>' respectively, and not modified your print commands at all.

Of course, since you seem to wish to preserve stdout/stderr now, it'd be better to keep stdout/err as is.

A redirection can't cause something to print twice. If you want to print twice, you have to print twice. You can make a function to do so, however, simplifying things for you.

Code:
function output
{
        print "$@" >&3
        [ ! -z "$DEBUG" ] && print "$@"
}

function debug
{
        print "$@" >&4
        [ ! -z "$DEBUG" ] && print "$@" >&2
}

If you want to see the output appear on the screen, run it like DEBUG=1 ./myscript

or export the DEBUG variable in your shell or profile.

Last edited by Corona688; 07-23-2012 at 01:13 PM..
This User Gave Thanks to Corona688 For This Post:
# 3  
Old 07-23-2012
Corona688,

Thank you for the advice.

Multiple users in different parts of my organization will end up using this script. I decided to write to 3 and 4 because I did not want other users controlling where the log files got written, such as by calling the script as:
Code:
 
myscript.ksh > /some/other/location/output.log 2>&1

I'm paranoid; I hope that is forgivable. Smilie

... I think I understand what you're saying, though.

Even if someone does try to co-opt my output using the redirect shown above, the script wrangles the output I defined for 2, overriding the other users' redirects.

I tried it and it seems to work that way. Thanks! I never thought about doing it this way.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Redirecting stdout output to whiptail menu box

As a result of whiptail menu option I am getting a data from a file. Naturally it is output to terminal as stdour. I like to redirect the output back to the menu. It can be done with single input of line of text , see attached. I just cannot see where or how the sample... (0 Replies)
Discussion started by: annacreek
0 Replies

2. Shell Programming and Scripting

Redirecting STDERR to file and screen, STDOUT only to file

I have to redirect STDERR messages both to screen and also capture the same in a file but STDOUT only to the same file. I have searched in this formum for a solution, but something like srcipt 3>&1 >&2 2>&3 3>&- | tee errs doesn't work for me... Has anyone an idea??? (18 Replies)
Discussion started by: thuranga
18 Replies

3. Shell Programming and Scripting

Redirecting stdout continously to a file

I have a C program that continously outputs info to stdout. The problem is that I am redirecting the stdout and stderr to a file and stdout is written at the end of the problem rather than continously to the file. This could be a problem if for example the program is killed and the stdout output is... (3 Replies)
Discussion started by: igurov
3 Replies

4. Shell Programming and Scripting

Redirecting stdout problem

I have a simple bash script that prints sth every 5 seconds. What I do is the following. I redirect the output of the script to a file, tail the file and see that it works and then from another console I delete the file where the output is redirected to. Even though I have deleted the file, the... (2 Replies)
Discussion started by: igurov
2 Replies

5. Shell Programming and Scripting

Preserve output order when redirecting stdout and stderr

Hi, I already searched through the forum and tried to find a answer for my problem but I didn't found a full working solution, thats way I start this new thread and hope, some can help out. I wonder that I'm not able to find a working solution for the following scenario: Working in bash I... (8 Replies)
Discussion started by: Boemm
8 Replies

6. UNIX for Dummies Questions & Answers

Redirecting several outputs to /dev/stdout

I have an executable that, depending on its input, outputs to either one file or several. It usually prints nothing on screen. The usual way to call this program is to specify an input and output filenames, like this: ./executable.exe -i inputfile -o outputfileIt will then try to use the output... (1 Reply)
Discussion started by: aplaydoc
1 Replies

7. Shell Programming and Scripting

Redirecting part of output to stdout

Hi, I am trying to execute a command like this: find ./ -name "*.gz" -exec sh -c 'zcat {} | awk -f parse.awk' \; >> output If I want to print the filename, i generally use the -print argument to the find command but when I am redirecting the output to a file, how can I print just the... (2 Replies)
Discussion started by: Legend986
2 Replies

8. Shell Programming and Scripting

implicitly redirecting stdout to a file

Is there a way to redirect all stdout to a file implicitly - like defining stdout=/home/me/process.log - so that all "echo" commands in several scripts/subscripts are written to that file; instead of having to edit all scripts to redirect the "echo" (e.g. echo 'This is a test ' >>... (1 Reply)
Discussion started by: ALTRUNVRSOFLN
1 Replies

9. Shell Programming and Scripting

Redirecting STDERR message to STDOUT & file at same time

Friends I have to redirect STDERR messages both to screen and also capture the same in a file. 2 > &1 | tee file works but it also displays the non error messages to file, while i only need error messages. Can anyone help?? (10 Replies)
Discussion started by: vikashtulsiyan
10 Replies

10. Linux

vgscan produces no output using file descriptors on Oracle Enterprise Linux.

I wrote a simple program which will create a child process to execute a command and the output will be redirected to the file. Please have a look at the following code -> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> void execute(char **argv) { ... (0 Replies)
Discussion started by: sandiworld
0 Replies
Login or Register to Ask a Question