I'm using tcsh, and have to source a group .cshrc file. This file echoes some messages, which is fine for normal shells, but causes problems with programs like scp and rsync. I can see the solution taking one of a few forms, but am unable to implement any of them.

Only execute echos when appropriate

I've scoured the rsync and tcsh man pages, but I can't find any variables that are guaranteed to be set or unset when it is called from ssh/rsync/whatever. $PROMPT is the same as normal, $shlvl is 1, and nothing else looks promising.

Redirect to stderr

rsync/scp/etc don't seem to care about what comes over stderr, so if I could, I would

echo $MSG >&2

But this doesn't even work from the shell. Instead, it writes $MSG to a file named 2. When I look through the history, it seems that something (xterm? readline? tcsh?) is inserting spaces, so what was actually run was

echo $MSG > & 2

So the observed behavior makes sense given the actual input to tcsh.

Redirect to /dev/stderr

I've also tried

echo $MSG > /dev/stderr

Which works for ssh, but for scp and rsync, I get the message '/dev/stderr: Permission denied.' and the key difference seems to be where the file is symlinked. Adding ls -l /dev/stderr /proc/self/fd/2 to the cshrc file shows

# For ssh
lrwxrwxrwx 1 root root    15 Apr 11 09:58 /dev/stderr -> /proc/self/fd/2
lrwx------ 1 <me> <mygrp> 64 May 24 14:34 /proc/self/fd/2 -> /dev/pts/6

# For scp
lrwxrwxrwx 1 root root    15 Apr 11 09:58 /dev/stderr -> /proc/self/fd/2
l-wx------ 1 <me> <mygrp> 64 May 24 15:07 /proc/self/fd/2 -> pipe:[378204842]

However, since the permission denied message comes across on stderr, the scp/rsync process is able to do its thing, so I can live with this solution, but would rather not get this spurious error message.


The idiom I use is

if ( $?prompt ) then
    # interactive commands here

note that it's spelled $prompt (lowercase), not $PROMPT.

% echo $prompt

% ssh localhost 'echo $prompt'
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
prompt: Undefined variable.

If $prompt is always set, then one of your startup files might be setting it unconditionally.

It should go inside the if ( $?prompt ) test too, e.g.

if ( $?prompt ) then
    set prompt='%B%m%b %C3>'

    # interactive commands here

Testing if the output is a terminal might work too.

if ({ test -t 0 }) then
    # interactive commands here
  • thanks, but for some reason, my $prompt is always %B%m%b %C3> – Nate Parsons May 24 '12 at 16:09
  • Is it being set in your group .cshrc? Move the set prompt... inside the if ( $?prompt ) test as well. – Mikel May 24 '12 at 16:20
  • You're right. Shortly after I posted my comment, I found where $prompt was being set, and fixed things as you suggested. test -t 0 works for me also. – Nate Parsons May 24 '12 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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