tcsh 和其他 shell 之間的 stderr 重定向不一致
我在 tcsh 中遇到了重定向問題。
考慮以下命令:
vi --version
和vi --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
和--version
exitvi
。來自
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 中……