プログラム (Steam) のすべての出力を /dev/null にリダイレクトして、ターミナルに表示されないようにしようとしています。
私が試したことは次のとおりです
steam & > /dev/null 2>/dev/null
。steam & > /dev/null 2>&1
どちらもメッセージをまったく抑制しません (私が知る限り)。
私の理解では、& はプロセスを端末から切り離し、> は入力/出力をリダイレクトし、デフォルト/空白は stdout、2> は stderr になります。これら 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
シェル組み込みを使用し、すべての引数を で渡すことに注意してください$@
。
したがって、シェル出力リダイレクトの通常の解決策は次のようになります。@Adobe と @Gary の回答、この特定のタイプのケースでは、より微妙なアプローチと、舞台裏で何が起こっているかを理解することがしばしば必要になります。 のすべての可能な出力リダイレクト方法と操作順序がsteam
期待どおりに機能しないことがある理由については、微妙な点があります。
シェルexec
組み込み(最初のニュアンス)
POSIX標準では、コマンドexec
Bashはこれを提供しますexec
シェル組み込み呼び出し方法に応じて、標準の IO リダイレクトとサブプロセス ツリーに影響を与える可能性があります。 注記:これは厳密には OP の特定のユースケースやリストされたコマンドには当てはまりませんが、よくある落とし穴であり注意すべき点であるため、ここに含めています。
IEEE Std. 1003.1、2004年版より:
exec ユーティリティは、コマンドの一部としてリダイレクトによって指定されたとおりに、ファイル記述子を開いたり、閉じたり、コピーしたりします。
exec がコマンドまたは引数なしで指定され、2 より大きい番号を持つファイル記述子が関連付けられたリダイレクト ステートメントで開かれている場合、シェルが別のユーティリティを呼び出すときにそれらのファイル記述子が開いたままになるかどうかは指定されていません。子シェルが開いているファイル記述子を誤用する可能性があるスクリプトでは、次の例のいずれかに示すように、常にそれらのファイル記述子を明示的に閉じることができます。
exec が command とともに指定されている場合、新しいプロセスを作成せずにシェルを command に置き換えます。arguments が指定されている場合、それらは command への引数となります。リダイレクトは現在のシェル実行環境に影響します。
exec /usr/lib/steam/steam "$@"
ラッパー スクリプトの行は、新しいサブプロセスを作成せずに、/usr/bin/steam
実行中のシェルを置き換えます("shebang 行に従って)。引数指定子は二重引用符で渡されるため、ほとんどの場合、IO リダイレクト演算子による副作用は回避されます。ただし、出力リダイレクト演算子を引数として渡すと (たとえば、誤った引用符経由、またはエスケープ文字を使用した経由)、スクリプトにシェル リダイレクト演算子が挿入される可能性があり、呼び出しがコマンドの標準 IO およびファイル記述子に影響を与える可能性があることに注意してください。そのため、、またはその他のリダイレクト演算子をラッパー スクリプトに渡す方法に応じて、それらは のコンテキストで評価されます。幸いなことに、この場合の二重引用符によってほとんどの副作用が排除されますが、どの bash プロセスまたはサブシェルがそれらの引数を評価しているかに注意することが重要です。/bin/bash
$@
"
'
eval
\
exec
2>&1
>somefile
"$@"
Unix 出力リダイレクト: stdin
、、stdout
&stderr
ほとんどのUnix再生産シェルには同様のリダイレクト方法があり、標準IOストリーム、、、および。これには、POSIX 、Bash、Z Shell 、Korn Shell 、C Shell 、Dashなどstdin
が含まれますが、これらに限定されません。stdout
stderr
sh
zsh
ksh
csh
dash
OPの質問の目的のために、/usr/bin/steam
ラッパースクリプトがBashで始まるため、Bashのみに焦点を当てます。シバン" ライン:#!/bin/bash
。
Bash では、最初の 3 つのファイル記述子 ( fd
) は常に次のように定義され、ゼロからインデックスが付けられます0
。
stdin
=fd 0
stdout
=fd 1
stderr
=fd 2
任意のコマンドの出力は、Bash の出力リダイレクト演算子 (Bash リファレンスマニュアル: § 3.6 リダイレクト)これについての基本的な紹介は、この記事でご覧いただけます。記述子を使った Bash リダイレクトの楽しみ視覚的な補助を使ってより直感的に説明するには、この素晴らしい記事をご覧ください(強くお勧めします!)。
演算順序(2番目のニュアンス):
以下の操作の間には微妙な順序があります。
- リダイレクト演算子(
>
、、、、、、、、、、、、など)<
>>
<<
&>
&>>
X<&Y
X>&Y
X>|Y
X<&Y-
X<>Y
... そしてその:
- 制御演算子(
&
、、;
/ 、、、、、、、、、)。\n
newline
||
&&
;;
;&
;;&
|
|&
(
)
からBash リファレンスマニュアル § 3.6 リダイレクト:
リダイレクトは、左から右へ、表示される順序で処理されます。
[...をちょきちょきと切る...]
リダイレクトの順序は重要であることに注意してください。たとえば、コマンド
ls > dirlist 2>&1
は標準出力(ファイル記述子1)と標準エラー(ファイル記述子2)の両方をファイルdirlistに出力しますが、コマンド
ls 2>&1 > dirlist
標準出力が dirlist にリダイレクトされる前に、標準エラーが標準出力のコピーとして作成されたため、標準出力のみがファイル dirlist に送信されます。
&
同様に、やその他の制御演算子にも演算順序があります。
からBash リファレンスマニュアル: 2.4 コマンドのリスト:
リストは、演算子 '
;
'、'&
'、'&&
'、または '||
' のいずれかで区切られた 1 つ以上のパイプラインのシーケンスであり、オプションで ' ';
、'&
'、または 'のいずれかで終了できますnewline
。これらのリスト演算子のうち、 '
&&
' と '||
' は同じ優先順位を持ち、次に ';
' と '&
' が同じ優先順位を持ちます。
list
コマンドを区切るために、セミコロンと同等の1 つ以上の改行のシーケンスが 内に表示される場合があります。
最後に、具体的には次のセクションについてです&
。
コマンドが制御演算子 '
&
' で終了した場合、シェルはサブシェルでコマンドを非同期的に実行します。これは、コマンドをサブシェルで実行すると呼ばれます。背景これらは非同期コマンド。シェルはコマンドの終了を待たず、戻りステータスは0
(true
)です。ジョブ制御がアクティブでない場合(ジョブコントロール) の場合、明示的なリダイレクトがない場合、非同期コマンドの標準入力は からリダイレクトされます/dev/null
。
OPのコマンドが期待通りに動作しなかった理由
最初に試した 2 つのコマンドは次のとおりです。
steam & > /dev/null 2>/dev/null
steam & > /dev/null 2>&1
これらが両方の意図されたリダイレクトを実行しなかった理由は、stdout
前述stderr
のとおりです。演算の順序 / 演算子の優先順位上に挙げたルールに従って、&
演算子は左から右の順に最初に現れます。最初の単語であるコマンドに適用され、steam
バックグラウンドで実行され、非同期コマンドは stdin
に接続され/dev/null
、stdout
と はstderr
制御に接続されたままである擬似端末 /pty
これについては以下でさらに詳しく説明します。
でもまず...