find
通常のユーザーとして時間指定コマンドを実行しています。
私が知っていることは、リダイレクトは端末上の stdout/stderr メッセージを防ぐためだということです。そうだとしたら、リダイレクト方法によってかかる時間が異なるのはなぜでしょうか? これは tty の書き込み速度と何らかの関係があるのでしょうか、それとも他の理由があるのでしょうか? これを理解する上で正しい方向を教えていただけませんか?
$ id
uid=1000(user1) gid=1000(user1) groups=1000(user1),1001(user2)
$time find /
<truncated output>
real 0m13.902s
user 0m0.197s
sys 0m0.448s
$ time find / >/dev/null
<truncated output>
real 0m0.298s
user 0m0.068s
sys 0m0.206s
$time find / 2> /dev/null
<truncated output>
real 0m13.279s
user 0m0.181s
sys 0m0.405s
$ time find / > /dev/null 2>&1
real 0m0.306s
user 0m0.109s
sys 0m0.174s
答え1
プロセス ( find
) が実際に出力を書き出す必要がある場合、その出力を破棄するように指示した場合よりも明らかに時間がかかります。
を使用すると
find /
、stdoutとstderrの両方が端末に送信され、両方を書き出す必要があります(つまり、実際の結果とすべての権限エラーなど)。を使用すると、
time find / >/dev/null
コマンドの標準出力は削除されますが、エラーがあればすべて出力されます。結果から判断すると、正当な結果がたくさんあり、エラーはほとんどありません。を使用すると
time find / 2> /dev/null
、コマンドの標準出力は引き続き端末に送信されますが、今度は単に stderr が削除されるだけです。読み取り権限のないファイルシステムを検索する場合、これは実際にはかなり高速になります。を使用すると
time find / > /dev/null 2>&1
、標準出力が削除され、標準出力が送信される場所に標準エラーが送信されます。つまり、両方が削除されます。これは何も出力しないため、すべてのコマンドの中で最も高速になります。
答え2
私が知っていることは、リダイレクトはターミナル上の stdout/stderr メッセージを防ぐためだということです。
いいえ、ファイルにリダイレクトすることもできます。
find / > ~/all-the-files
これは tty の書き込み速度と何らかの関係があるのでしょうか?
一言で言えば、そうです。
使用している端末の種類 (Linux の仮想コンソール、ローカル xterm、SSH 接続経由のもの) に関係なく、実際の端末エミュレーターは、端末に表示されるすべてのものを描画する必要があります。ただし、この場合はすぐにスクロールアウトします (接続経由の場合はmosh
例外になる場合があります)。
ネットワーク接続では、転送遅延も考慮する必要があります。大量のデータがある場合、一部のデータはバッファリングされますが、すべてではありません。何かを にリダイレクトすると/dev/null
、どこにも保存されず、描画もされません。ファイルへのリダイレクトも、中程度のデータ量であれば高速です。これは、OS が書き込みをメモリにキャッシュし、その後で実際にディスクに書き込むためです。大量のデータがある場合、ディスクへの書き込みもボトルネックになる可能性があります。(または、プロセスに同期 I/O モードで出力を書き込ませることができれば)
大量の出力を行うプログラムの場合、printf()
データが にリダイレクトされたとしても、出力をフォーマットするプロセス ( プロセス内) と OS に書き込むよう呼び出すプロセスだけで時間がかかります/dev/null
。このような場合、プログラムに出力を完全に禁止させることができれば、さらに高速化できる可能性があります。 の場合はおそらくそうではないでしょうがfind
、I/O 速度またはシステム コールのオーバーヘッドが原因だと思います。
また、同じディレクトリ ツリーで繰り返し実行する場合find
、最初の実行ではディスクからの読み取りが必要になる可能性があり、その後はデータの多くが OS によってキャッシュされるため、最初の実行は他の実行よりも遅くなる可能性があります。