Io-Redirection

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

  • January 26, 2019

我在 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

這種不一致實際上是csh 程式被認為有害的原因列表中的第一個原因。

或者,如果您只想丟棄 stderr 並不理會 stdout 怎麼辦?操作很簡單吧?

cmd 2>/dev/null

在 Bourne shell 中工作。在csh中,你只能做這樣一個可憐的嘗試:

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

但是誰說 stdout 是我的 tty?所以這是錯誤的。這個簡單的操作不能在 csh 中完成。

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 中……

引用自:https://unix.stackexchange.com/questions/197878