Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

From within a shell script (sh/bash), how can I tell what device or file name I am redirecting to?

For example, I have a shell script named script.sh.

I run the shell script and redirect STDOUT to a file named out.txt, and redirect STDERR to a file named err.txt.

So, that would look like this:

$ ./script.sh > out.txt 2> err.txt

Now, from within the shell script, I can tell if STDOUT (or STDERR) is being redirected, or not:

if [ -t 1 ]; then...
if [ ! -t 1 ]; then...

but, once I know STDOUT (or STDERR) is being redirected, how can I tell where it is being rdirected to?

share|improve this question
    
Why would the script need to care? –  Ignacio Vazquez-Abrams Feb 9 at 5:04
    
@IgnacioVazquez-Abrams - The script will run for hours and will generate many Gigabytes of output. I want to (every so often) check the size of the redirect file and restart the script with redirection to a different file if (when) it gets larger than some size (the script is written so that it can be stopped and restarted, and it will resume where it was before it was stopped). –  Kevin Fegan Feb 9 at 5:23
1  
That's something the external script should be handling. The one that knows where it's redirecting to. –  Ignacio Vazquez-Abrams Feb 9 at 5:23
    
@IgnacioVazquez-Abrams - The script is being started from the command line. I could write a "wrapper" script to start the main script, and the "wrapper" would know the name of the redirect file, but once the "wrapper" calls the main script, the "wrapper" waits (does nothing) until the main script completes and exits... by then, it would be meaningless for the "wrapper" script to check the redirect file anymore. –  Kevin Fegan Feb 9 at 5:35
    
@IgnacioVazquez-Abrams - If the answer to my question is that "it can't be done", then I can find workarounds involving various ways of passing the name of the redirect file to the main script, or starting the mainscript in the background, and let the "wrapper" monitor the redirect file. But all this adds levels of unnecessary complexity if what I'm asking can be done. –  Kevin Fegan Feb 9 at 5:40

2 Answers 2

up vote 2 down vote accepted

You could use lsof:

/usr/sbin/lsof -p $$ -a -d 1

The above would list just file descriptor 1 for just the current process:

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    5054 matt    1u   CHR  136,1      0t0    4 /dev/pts/1
share|improve this answer
    
Thank you. THis is probably what I wanted. But, unfortunately, lsof is not found on my machine. Here is my output of uname: Linux 3.2.52 #9 SMP Tue Oct 29 11:08:09 CDT 2013 x86_64 GNU/Linux –  Kevin Fegan Feb 9 at 12:50
    
It's found in /usr/sbin rather than /usr/bin, so if sbin isn't the the PATH for your script that's the problem. If it's not in sbin either, then use your distribution's package manager to get the lsof package. –  Matthew Cline Feb 9 at 17:48
    
Eureka! I found it in /usr/sbin. It seems to be working. I ran it as "/usr/sbin/lsof -p $$ -a -d 1", and it came back with hundreds of warnings like: "lsof: WARNING: can't stat() ext4 file system /home/...folder". So, I added the "-w" switch. And, in order to only get the file-size and filename, I also added "-Fsn". Running "/usr/sbin/lsof -p$$ -a -d 1 -w -Fsn" produced: "p1234 \n s288355 \n n/home/...path/filename". So, I needed to use grep and sed to remove the "p1234" (PID) line, and the leading "s" and "n" before the file-size and filename. –  Kevin Fegan Feb 10 at 22:23

You generally do things such as "watch" scripts, by watching them from the either the outside or from the script that called this subordinate script.

$ ./script.sh > out.txt 2> err.txt &
[1] 6280

Now we watch:

$ watch "ls -l out.txt err.txt"
Every 2.0s: ls -l out.txt err.txt                        Sun Feb  9 00:30:37 2014

-rw-rw-r--. 1 saml saml 0 Feb  9 00:30 err.txt
-rw-rw-r--. 1 saml saml 0 Feb  9 00:30 out.txt

Every 2 seconds (you can change this) the output will get updated:

Every 2.0s: ls -l out.txt err.txt                        Sun Feb  9 00:30:39 2014

-rw-rw-r--. 1 saml saml 200 Feb  9 00:30 err.txt
-rw-rw-r--. 1 saml saml 200 Feb  9 00:30 out.txt
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.