Search code examples
filehttp-redirectstderrcshtcsh

stderr redirection methods


I am running tcsh/csh shell on my machine. lately i have realized my stderr file redirection is not working.

Please find the terminal logs as below:

>echo b c >>& log
>cat log
b c
>echo $a b c >>& log
a: Undefined variable.
>cat log
b c

I have never faced such issues, hence not sure how to debug or troubleshoot. Please advice!

An alterate method of redirection is using tee. While I use >& or >>& , i am altogether blocking any output to be displayed on terminal. Is there a way I can do both, that is: for each statement

a) direct stdout+stderr to a file.

b) display stdout+stderr on terminal

I need to confirm if i can use something like this(below) to meet my requirements

>csh ./script_name | tee -a log

In my case it only directs stdout to log file and blocks stderr.


Solution

  • I'm pretty certain that the evaluation of $a is being done by the current shell, before the redirection is set up for the echo subshell?

    It seems to be supported by the fact that the echo isn't actually writing to the file at all, which you could see if you deleted the log file before the second attempt:

    [pax ~]$ echo b c >>& log
    
    [pax ~]$ cat log
    b c
    
    [pax ~]$ rm log
    
    [pax ~]$ echo $a b c >> & log
    a: Undefined variable.
    
    [pax ~]$ cat log
    cat: log: No such file or directory
    

    And also by the fact that, if you run the echo in an explicit subshell with the redirection done for the subshell rather than the echo, you get your desired result:

    [pax ~]$ ( echo $a b c ) >> & log
    
    [pax ~]$ cat log
    b c
    a: Undefined variable.
    

    In fact, you can see this without even using a valid command:

    [pax ~]$ rm log
    
    [pax ~]$ $xyzzy
    xyzzy: Undefined variable.
    
    [pax ~]$ $xyzzy >>&log
    xyzzy: Undefined variable.
    
    [pax ~]$ cat log
    cat: log: No such file or directory
    

    The reason for this is that the current shell is complaining about trying to evaluate $xyzzy. This makes sense. With the command:

    someCmd $HOME
    

    the someCmd executable will never see the literal $HOME, it's actually replaced with the value. And that replacement is done by the shell before someCmd is even set up (including having its standard input or output streams modified).