2

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?

6
  • Why would the script need to care? Commented Feb 9, 2014 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). Commented Feb 9, 2014 at 5:23
  • 1
    That's something the external script should be handling. The one that knows where it's redirecting to. Commented Feb 9, 2014 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. Commented Feb 9, 2014 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. Commented Feb 9, 2014 at 5:40

2 Answers 2

3

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 
3
  • 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 Commented Feb 9, 2014 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. Commented Feb 9, 2014 at 17:48
  • 1
    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. Commented Feb 10, 2014 at 22:23
1

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 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.