tcsh 和其他 shell 之间的 stderr 重定向不一致

tcsh 和其他 shell 之间的 stderr 重定向不一致

我在 tcsh 中遇到重定向问题。

考虑以下命令:vi --versionvi --xxx。我们假设这是在vi支持该--version选项的机器上。该选项--xxx无效,因此vim应该通过 来显示一些内容stderr

根据这个推理,2> /dev/null与这两个命令一起使用应该为有效情况提供输出,而为无效情况不提供输出。

然后我在 bash、zsh、ksh 和 dash 中看到的内容。

$ vi --xxx 2> /dev/null
$ vi --version 2> /dev/null
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Oct 20 2014 16:09:17)
...

然而,当我在 tcsh 中尝试这个时,它给了我无输出两个都案例。

$ vi --xxx 2> /dev/null
$ vi --version 2> /dev/null
(there is no output here)

这里发生了什么?我重定向stderr错误吗?

这是输出tcsh --version

tcsh 6.18.01 (Astron) 2012-02-14 (i686-intel-linux) options wide,nls,dl,al,kan,rh,nd,color,filec

答案1

这种不一致实际上是原因列表中的第一个原因csh 编程被认为是有害的

或者如果您只想扔掉 stderr 并保留 stdout 该怎么办?操作很简单吧?

cmd 2>/dev/null

在 Bourne shell 中工作。在csh中,只能做这样的可怜尝试:

(cmd > /dev/tty) >& /dev/null

但谁说 stdout 是我的 tty?所以这是错的。这个简单的操作无法完成在csh中。

答案2

2>不是 中的运算符tcsh,您正在使用该>运算符并2作为参数传递给vi。这出现就可以了,因为--xxx--versionexit vi

tcsh(1)

   > name
   >! name
   >& name
   >&! name
           The file name is used as standard output.  If the file does not
           exist then it is created; if the file exists, it is  truncated,
           its previous contents being lost.

           If  the shell variable noclobber is set, then the file must not
           exist or be a character  special  file  (e.g.,  a  terminal  or
           `/dev/null')  or an error results.  This helps prevent acciden‐
           tal destruction of files.  In this case the `!'  forms  can  be
           used to suppress this check.

           The  forms  involving  `&' route the diagnostic output into the
           specified file  as  well  as  the  standard  output.   name  is
           expanded in the same way as `<' input filenames are.

所以你可以使用>&重定向两个都标准输出和标准错误(“诊断输出”)。没有“明显”的方法仅有的重定向stderr,这是C shell的一个长期存在的缺点,一个众所周知的解决方法是:

(vi --xxx > /dev/tty) >& /dev/null

这是通过将 stdout 重定向到/dev/tty子 shell 中的(当前的 tty)(括号的作用与 bourne shell 中相同)来实现的,并且子 shell 的输出(因为我们重定向了 stdout,所以只是 stderr)被重定向到/dev/null(但是这个可以是任何东西,比如文件)。

我不知道您的目标是什么,但在您无法确定用户正在使用什么 shell 的情况下,我发现通常最好显式设置它;有比“bourne 和 csh”更多的 shell,例如 Fish,并且不同的 Bourne shell 之间也可能存在轻微的不兼容性和/或某些结构可能“碰巧”在一个 shell 中工作,但在另一个 shell 中却不起作用...

相关内容