Shell

為什麼“nohup command >& /dev/null”在某些 shell 中似乎“工作”?

  • October 29, 2018

我在 Ask Ubuntu 上編輯了一個答案,建議如下

nohup gedit >& /dev/null & 

當他們真正的意思是

nohup gedit &> /dev/null & 

後者正確地將 stderr 和 stdout 重定向到/dev/null. 我期望前者要麼創建一個名為的文件,要麼&更有可能像其他情況一樣給出錯誤:

$ echo "foo" >& 
bash: syntax error near unexpected token `newline'

相反,它似乎以與前者完全相同的方式工作,出現一個gedit視窗並且不列印任何錯誤消息。

我還應該注意,這是特定於 shell 的:

  • bash(4.2.45(1)-release), zsh(5.0.2), csh(deb package version: 20110502-2) 和tcsh(6.18.01) : 如上所述工作,沒有錯誤消息,沒有創建文件。
  • dash(0.5.7-3):
$ nohup gedit >& /dev/null & 
$ dash: 2: Syntax error: Bad fd number
  • ksh(93u+ 2012-08-01): 失敗,但一個程序顯然已啟動 ( 1223) 儘管沒有gedit出現視窗:
$ nohup gedit >& /dev/null & 
[1] 1223
$ ksh: /dev/null: bad file unit number
  • fish(2.0.0):
> nohup gedit >& /dev/null & 
fish: Requested redirection to something that is not a file descriptor /dev/null
nohup gedit >& /dev/null & 
              ^

那麼,為什麼這個命令在某些 shell 中簡單地執行而沒有錯誤(並且沒有創建輸出文件)而在其他 shell 中失敗?>&在明顯的特殊情況下做什麼nohup?我猜這>& /dev/null被解釋為>&/dev/null但為什麼空間不會導致這些外殼中的錯誤?

nohup gedit &> /dev/null

是 POSIX 語法,與以下內容相同:

nohup gedit &
> /dev/null

那是nohup gedit在後台執行,然後在> /dev/null不執行命令的情況下進行重定向。

nohup gedit >& /dev/null

不是 POSIX 語法,而是csh將 stdout 和 stderr 都重定向到 /dev/null 的方法。csh沒有2>&1Bourne 中的運算符,因此這是csh重定向 stderr 的唯一方法。

zsh(通常)也提供csh語法,但它也支持 Bourne shell 的x>&y fd 重複運算符,這意味著那裡存在衝突。

ls >&file

ls將的 stdout 和 stderr重定向到file,但如果文件是2,那麼您會遇到問題

ls >&2

表示將標準輸出重定向到 fd 2 ( ) 指向的資源dup(2, 1)。所以你需要這樣寫:

ls >& ./2

如果您想將 stdout 和 stderr 都重定向到目前目錄中ls呼叫的文件中;2或使用標準語法。

bash最初不理解>&,但它&>為此引入了操作符,在此過程中破壞了 POSIX 合規性(儘管腳本不太可能使用cmd &> xxx)。

ksh2009 年在 ksh93t+ 中複製了該運算符,在 2008 年在 R35 中複製了 mksh(在posix模式下禁用)但不是>&.

bash``>&在 2.05 中增加了對的支持。

busybox在 1.13 (2008) 中sh增加了對兩者的支持&>>&

既不>&是也不&>是重定向 stdout 和 stderr 的意思是 POSIX/Bourne。

如果你想同時重定向標準輸出和標準錯誤,語法是

cmd > file 2>&1

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