我正在使用tcsh
,并且必须获取组.cshrc
文件。该文件回显一些消息,这对于普通 shell 来说没问题,但会导致scp
和等程序出现问题rsync
。我可以看到解决方案采用几种形式之一,但无法实施其中任何一种。
仅在适当的时候执行 echo
我已经浏览了rsync
和tcsh
手册页,但我找不到任何在从 ssh/rsync/whatever 调用时保证设置或取消设置的变量。$PROMPT
与正常情况相同,$shlvl
为 1,其他看起来没什么希望。
重定向到标准错误
rsync/scp/etc 似乎并不关心 stderr 上发生的事情,所以如果可以的话,我会
echo $MSG >&2
但这甚至在 shell 中都不起作用。相反,它会写入$MSG
名为 的文件2
。当我查看历史记录时,似乎有什么东西(xterm?readline?tcsh?)插入了空格,所以实际运行的是
echo $MSG > & 2
因此,考虑到 tcsh 的实际输入,观察到的行为是有意义的。
重定向到/dev/stderr
我也尝试过
echo $MSG > /dev/stderr
这适用于ssh
,但对于scp
和rsync
,我收到消息“ /dev/stderr: Permission denied.
”,关键区别似乎在于文件符号链接的位置。添加ls -l /dev/stderr /proc/self/fd/2
到cshrc文件显示
# 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]
但是,由于权限被拒绝的消息出现在 stderr 上,scp/rsync 进程能够执行其工作,所以我可以接受这个解决方案,但不想收到这个虚假的错误消息。
答案1
我使用的习语是
if ( $?prompt ) then
# interactive commands here
endif
请注意,它是拼写的$prompt
(小写),而不是$PROMPT
。
% echo $prompt
%U%m%u:%B%~%b%#
% ssh localhost 'echo $prompt'
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Password:
prompt: Undefined variable.
如果$prompt
始终设置,则您的启动文件之一可能会无条件地设置它。
它也应该进入if ( $?prompt )
测试内部,例如
if ( $?prompt ) then
set prompt='%B%m%b %C3>'
# interactive commands here
endif
测试输出是否是终端也可能有效。
if ({ test -t 0 }) then
# interactive commands here
endif