我試圖將程式(Steam)的所有輸出重定向到 /dev/null,這樣它就不會顯示在終端中。
這是我嘗試過的:
steam & > /dev/null 2>/dev/null
和steam & > /dev/null 2>&1
兩者都不會抑制它的消息(據我所知。)
我的理解是 & 將進程與終端分離,並且 > 重定向輸入/輸出,預設/空白 > 是標準輸出,2> 是標準錯誤。還有比這兩個更多的輸出嗎?如果我將所有輸出都重定向掉,為什麼我仍然可以看到輸出?
答案1
嘗試:
steam 2>&1 > /dev/null &
2>&1
將 stderr 重定向到 stdout,並將> /dev/null
stdout 重定向到/dev/null
.
後台&
進程放錯地方了。它必須位於該行的末尾。如果放置在之後steam
但之前>
,則不會steam
重定向任何內容,儘管該進程將正確後台運行。
答案2
這個特殊問題steam
恰好是一個特殊情況,有時需要一些特殊的理解和處理。運行steam
時是一個包裝腳本,包含以下內容:
#!/bin/bash
# default to minimize on close, so we never have a running steam process
# in the background because of a broken Tray Icon on some desktops/WMs
#export STEAM_FRAME_FORCE_CLOSE=${STEAM_FRAME_FORCE_CLOSE:-0}
exec /usr/lib/steam/steam "$@"
請注意,它使用exec
內建的 shell,並使用 傳遞所有參數$@
。
因此,雖然 shell 輸出重定向的常用解決方案類似於@Adobe 和@Gary 的回答,這種特殊類型的案件通常需要更細緻的方法並了解幕後發生的事情。為什麼所有可能的輸出重定向方法和操作順序steam
有時不能按預期工作,有一些微妙之處。
exec
內建外殼(第一個細微差別)
POSIX 標準定義了一種行為exec
命令。 Bash 透過以下方式提供此功能exec
外殼內置。這會影響標準 IO 重定向和子進程樹,這取決於它的呼叫方式。 筆記:雖然這在技術上並不適用於 OP 的特定用例和列出的命令,但我將其包含在這裡,因為這是一個需要注意的常見陷阱和警告。
來自 IEEE 標準。 1003.1,2004 年版:
exec 公用程式應按照作為命令一部分的任何重定向指定的方式開啟、關閉和/或複製檔案描述符。
如果在沒有命令或參數的情況下指定 exec,並且使用關聯的重定向語句開啟任何編號大於 2 的檔案描述符,則未指定當 shell 呼叫另一個實用程式時這些檔案描述符是否保持開啟狀態。擔心子 shell 可能濫用開啟的檔案描述符的腳本始終可以明確關閉它們,如以下範例之一所示。
如果用command指定exec,則用command取代shell,而不建立新進程。如果指定了參數,則它們應是命令的參數。重定向會影響目前的 shell 執行環境。
exec /usr/lib/steam/steam "$@"
包裝器腳本中的行將替換/usr/bin/steam
執行/bin/bash
shell(按照“shebang 行”),而不創建新的子進程$@
。 ,值得注意的是,傳入一些輸出重定向運算子作為參數(例如透過錯誤的引號"
或'
透過eval
轉義字元\
)可能會提供將 shell 重定向運算子注入到腳本中的機會,這樣exec
呼叫可能會影響標準。2>&1
>somefile
"$@"
的是要小心哪個bash 進程或子shell 正在評估這些參數。
Unix 輸出重新導向:stdin
, stdout
, &stderr
大多數UnixREPLshell 有類似的重定向方法標準IO流,stdin
,stdout
, 和stderr
。這包括但不限於:POSIX sh
、Bash、Z Shell zsh
、Korn Shell ksh
、C Shell csh
、Dashdash
等。
出於 OP 問題的目的,我們將僅關注 Bash,因為/usr/bin/steam
包裝器腳本以 Bash 開頭“舍邦「 線:#!/bin/bash
。
在 Bash 中,前 3 個檔案描述符 ( fd
's) 始終定義如下,索引從零開始0
:
stdin
=fd 0
stdout
=fd 1
stderr
=fd 2
任何命令的輸出都可以使用重定向Bash 中的輸出重定向運算子(Bash 參考手冊:§ 3.6 重定向)。對此的基本介紹可以在這篇文章中找到:Bash 重定向與描述符的樂趣。為了透過視覺輔助工具獲得更直觀的解釋,請參閱這篇優秀文章(強烈推薦!)。
操作順序(第二個細微差別):
以下各項之間存在微妙的操作順序:
- 重定向運算符(
>
,<
,>>
,<<
,&>
,&>>
,X<&Y
,X>&Y
,X>|Y
,X<&Y-
,X<>Y
, ETC...)
……以及:
- 控制操作員(
&
,, / ,,,,,,,,,, ) 。;
\n
newline
||
&&
;;
;&
;;&
|
|&
(
)
重定向按照它們出現的順序從左到右進行處理。
[...剪...]
請注意,重定向的順序很重要。例如,命令
ls > dirlist 2>&1
將標準輸出(檔案描述符 1)和標準錯誤(檔案描述符 2)定向到檔案目錄列表,而命令
ls 2>&1 > dirlist
僅將標準輸出定向到檔案 dirlist,因為在標準輸出重定向到 dirlist 之前,標準錯誤是標準輸出的副本。
&
類似地,和 其他控制操作符也有操作順序。
清單是由運算子 '
;
'、'&
'、'&&
' 或 ' ' 之一分隔的一個或多個管道的序列,並且可以選擇以 ' '、' ' 或 '||
之一終止。;
&
newline
在這些列表運算符中,“
&&
”和“||
”具有相同的優先級,其次是“;
”和“&
”,它們具有相同的優先權。一系列的一個或多個換行符號可能出現在
list
分隔命令中,相當於分號。
最後,特別是關於以下內容的部分&
:
如果命令由控制運算子「
&
」終止,則 shell 會在子 shell 中非同步執行該命令。這稱為執行命令背景,這些被稱為非同步命令。 shell 不等待指令完成,回傳狀態為0
(true
)。當作業控制未啟動時(參見作業控制),非同步指令的標準輸入,在沒有任何明確重定向的情況下,從 重定向/dev/null
。
為什麼OP的指令沒有達到預期的效果
嘗試的前兩個命令是:
steam & > /dev/null 2>/dev/null
steam & > /dev/null 2>&1
這些沒有執行預期的重新導向stdout
和stderr
預期的原因是由於上述原因運算順序/運算符優先級上面列出的規則。具體來說,&
運算符按從左到右的順序首先出現。它應用於第一個單詞,即命令steam
,並將其發送到後台運行非同步命令。 stdin
連接到/dev/null
,同時stdout
,並stderr
保持連接到控制偽終端 /pty
。這將在下面進一步解釋。
但首先...