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.

Is it possible, within a shell script, to write to the screen while STDOUT and STDERR is being redirected?

I have a shell script that I want to capture STDOUT and STDERR. The script will run for perhaps an hour or more, so I want to occasionally write some status messages to the screen that will be displayed and not redirected (not captured).

For a minimal example, I have a shell script, let's say "./myscript.sh":

#!/bin/sh -u

echo "Message A: This writes to STDOUT or wherever '1>' redirects to."
echo "Message B: This writes to STDOUT or wherever '1>' redirects to.">&1
echo "Message C: This writes to STDERR or wherever '2>' redirects to.">/dev/stderr
echo "Message D: This writes to STDERR or wherever '2>' redirects to.">&2
echo "Message E: Write this to 'screen' regardless of (overriding) redirection." #>???  


Then, for example, I'd like to see this output when I run the script like this:

[~]# ./myscript.sh > fileout 2> filerr
Message E: Write this to 'screen' regardless of (overriding) redirection.
[~]# ./myscript.sh > /dev/null 2>&1
Message E: Write this to 'screen' regardless of (overriding) redirection.
[~]#    


If this cannot be done "directly", is it possible to temporarily discontinue redirection, then print something to the screen, then restore redirection as it was?

Some info about the computer:

[~]# uname -srvmpio
Linux 3.2.45 #4 SMP Wed May 15 19:43:53 CDT 2013 x86_64 x86_64 x86_64 GNU/Linux

[~]# ls -l /bin/sh /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root  4 Jul 18 23:18 /bin/sh -> bash
lrwxrwxrwx 1 root root 15 Jun 29  2013 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 29  2013 /dev/stdout -> /proc/self/fd/1
share|improve this question
1  
echo msg > /dev/tty –  Stéphane Chazelas Jan 4 at 20:35
    
@strugee - I wanted to tag it with the OS: "GNU/Linux" but I wasn't allowed to (I even tried "GNU-Linux"), so I tagged as "GNU" and "Linux" individually. –  Kevin Fegan Jan 6 at 14:44
    
@StephaneChazelas - echo msg > /dev/tty. That worked! I was sure I tried this early on without success but I must have just tried other similar things. In any case it's working for me. If you'd like to put this as an answer, I'll mark it as accepted. –  Kevin Fegan Jan 22 at 17:50

2 Answers 2

Using the example from the answer by chaos:

echo "to screen" >$(tty)

did not work for me. I get an error when attempting to use it:

./myscript.sh: line xx: /dev/pts/3: Permission denied

I came up with a solution to use another file descriptor (9). Here is "./myscript.sh":

#!/bin/sh -u

## This is placed one time at the top of the script  
## to detect if file descriptor (9) is available for writing.
if [ ! -t 3 ]; then
    echo "Error, file descriptor (9) not open on terminal." >&2
    echo "" >&2
    if [ ! -t 2 ]; then
        echo "Error, file descriptor (9) not open on terminal."
        echo ""
    fi
    exit 1
fi

echo "Message A: This writes to stdout or wherever '1>' redirects to."
echo "Message B: This writes to stdout or wherever '1>' redirects to.">&1
echo "Message C: This writes to stderr or wherever '2>' redirects to.">/dev/stderr
echo "Message D: This writes to stderr or wherever '2>' redirects to.">&2
echo "Message E: Write this to 'screen' regardless of '1>/2>' redirection." >&9
echo " " >&9

I used file descriptor 9 to output the "status" messages to, but other valid file descriptors should work.

To use it, when calling the script, you have to include redirection of file descriptor (9) to STDOUT (9>&1) as the first redirection.

Here is the output when I call "./myscript.sh":

[~]# ./myscript.sh
[~]# ./myscript.sh >/dev/null
[~]# ./myscript.sh 2>/dev/null
Error, file descriptor (9) not open on terminal.

[~]# ./myscript.sh >/dev/null 9>&1
Error, file descriptor (9) not open on terminal.

[~]# ./myscript.sh 9>&1 >/dev/null
Message C: This writes to stderr or wherever '2>' redirects to.
Message D: This writes to stderr or wherever '2>' redirects to.
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]# ./myscript.sh 9>&1 2>/dev/null
Message A: This writes to stdout or wherever '1>' redirects to.
Message B: This writes to stdout or wherever '1>' redirects to.
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]# ./myscript.sh 9>&1 >/dev/null 2>&1
[~]# ./myscript.sh 9>&1 &>/dev/null
[~]# ./myscript.sh 9>&1 >&/dev/null
Message E: Write this to 'screen' regardless of '1>/2>' redirection.

[~]#
share|improve this answer

Try a script like this:

#!/bin/bash
echo "to fd1" >&1
echo "to fd2" >&2
echo "to screen" >$(tty)

When you call it, it looks like this:

user@host:~# ./script
to fd1
to fd2
to screen
user@host:~# ./script 1>/dev/null
to fd2
to screen
user@host:~# ./script 2>/dev/null
to fd1
to screen
user@host:~# ./script > /dev/null 2>&1
to screen
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.