/ dev / nullがファイルなのはなぜですか?その機能が単純なプログラムとして実装されていないのはなぜですか?


114

Linuxでの特殊ファイルの概念を理解しようとしています。しかし、/dev私の知る限り、Cのいくつかの行でその機能を実装できる場合、特別なファイルを持っているのはばかげているように見えます。

さらに、ほぼ同じ方法で使用することもできます。つまりnull、にリダイレクトする代わりにパイピングし/dev/nullます。ファイルとして持つ特定の理由はありますか?同じファイルにアクセスするプログラムが多すぎるなど、他の多くの問題をファイルにしないのですか?


20
ちなみに、このオーバーヘッドのcat foo | bar大部分も、なぜ(スケールで)がはるかに悪いのかですbar <foocat些細なプログラムですが、些細なプログラムでもコストが発生します(FIFOのセマンティクスに固有のものもあります。seek()たとえば、プログラムはFIFO内に配置できないためです。パイプラインが与えられた場合、/dev/nullそれらの操作を偽装できるキャラクターデバイスを使用するか、実際のファイルを使用してそれらを実装できますが、FIFOはコンテキストを意識した処理を一切許可しません)。
チャールズダフィー

13
grep blablubb file.txt 2>/dev/null && dosomethingnullがプログラムまたは関数であると機能しませんでした。
-rexkogitans

16
Plan 9オペレーティングシステムについて読んで、「すべてがファイルである」というビジョンがどこに向かっているのかを見ると、啓発的(または少なくとも精神拡張)に気付くかもしれません-ファイルとして利用可能なリソースを持つ力が少しわかりやすくなります(ほとんどの場合/部分的に、現代のLinux / Unixのように)概念を完全に受け入れているシステムを見た後のパス。
mtraceur

25
カーネル空間で実行されているデバイスドライバーが「ほんの数行のC」を含むプログラムであることを指摘する人 ないが、これまでのところ、「同じファイルにアクセスするプログラムが多すぎる」という仮定に実際に対処した回答はない質問で。
JdeBP

12
あなたはそれを信じられないだろうが、それは:再「その機能はCの行の一握りで実現することができ、」 Cの行の一握りによって実装します!たとえば、のread関数の本体は/dev/null「return 0」で構成されます(つまり、何も行わず、EOFが発生することを意味します):(静的github.com/torvalds/linux/blob/master/からdrivers / char / mem.cssize_t read_null(struct file *file, char __user *buf, size_t count, loff_t *ppos) { return 0; }(ああ、@ JdeBPがすでにその点を指摘しているのを見るだけです。とにかく、ここにイラストがあります:-)。
ピーターA.シュナイダー

回答:


153

キャラクター専用デバイスを使用することのパフォーマンス上の利点に加えて、主な利点はモジュール性です。/ dev / nullは、シェルパイプラインだけでなく、ファイルが予想されるほとんどすべてのコンテキストで使用できます。ファイルをコマンドラインパラメーターとして受け入れるプログラムを検討します。

# We don't care about log output.
$ frobify --log-file=/dev/null

# We are not interested in the compiled binary, just seeing if there are errors.
$ gcc foo.c -o /dev/null  || echo "foo.c does not compile!".

# Easy way to force an empty list of exceptions.
$ start_firewall --exception_list=/dev/null

これらはすべて、プログラムをソースまたはシンクとして使用することが非常に面倒な場合です。シェルパイプラインの場合でも、stdoutとstderrは独立してファイルにリダイレクトされる可能性があります。これは、実行可能ファイルをシンクとして実行するのは困難です。

# Suppress errors, but print output.
$ grep foo * 2>/dev/null

14
また/dev/null、シェルのコマンドだけでは使用しません。ソフトウェアに提供される他のパラメーターで使用できます---例えば構成ファイルで。---ソフトウェアを強化してください。これは非常に便利です。と/dev/null通常のファイルを区別する必要はありません。
パブーク

実行可能ファイルをシンクするための個別のリダイレクトが難しいという部分を理解しているかどうかはわかりません。Cでは、あなただけやるpipeforkexecveばかりに変更して、他のプロセス配管のようにdup2右、接続を設定呼び出し?これは、ほとんどのシェルはそれを行うためにきれいな方法を提供していない事実ですが、私たちはそんなにデバイスとしてファイルパターンを持っていると物事のほとんどではなかったと思われる場合/dev/proc、実行ファイルとして処理し、シェルは、さまざまな方法で設計されていたであろう今すぐリダイレクトするのと同じくらい簡単にできます。
アシェプラー

6
@ascheplerシンク実行可能ファイルにリダイレクトしないのは難しいことです。ヌルシンクがファイルではない場合、両方のファイルヌルシンクへの書き込み/読み取りが可能なアプリケーションの作成はより複雑になります。すべてがファイルである代わりに、すべてが実行可能ファイルである世界について話しているのでない限り、これは、* nix OSにあるモデルとは非常に異なるモデルです。
キュービック

1
@aschepler忘れてたwait4!確かに、POSIX apiを使用してstdoutとstderrを異なるプログラムにパイプすることは確かに可能です。また、stdoutとstderrを異なるコマンドにリダイレクトするための巧妙なシェル構文を発明することも可能です。しかし、私は現時点ではそのようなシェルを認識していません。大きなポイントは、/ dev / nullが既存のツール(ほとんどの場合ファイルで機能する)にきちんと収まり、/ bin / nullが収まらないことです。gccが(安全に!)ファイルへのプログラムへの出力を(安全に!)簡単にするIO APIを想像することもできますが、それは私たちの状況ではありません
ioctl

2
シェルに関する@ioctl。あなたのようなことを行うことができます少なくとも、zshのとbashの両方がgrep localhost /dev/ /etc/hosts 2> >(sed 's/^/STDERR:/' > errfile ) > >(sed 's/^/STDOUT:/' > outfile)、別々に処理され、得られerrfileかつoutfile
マティヤNalisを

62

公平には、それ自体は通常のファイルではありません。それはキャラクターの特別なデバイスです:

$ file /dev/null
/dev/null: character special (3/2)

ファイルまたはプログラムとしてではなくデバイスとして機能することは、標準の入出力/エラーを含む任意のファイル記述子に添付できるため、入力または出力のリダイレクトがより簡単な操作であることを意味します。


24
cat file | null最初またなど、パイプの設定プロセスを生成、新しいプロセスに「NULL」を実行する際に、オーバーヘッドの多くを有するであろう、nullそれ自体は後でバッファにバイトを読み込むループ内CPUのかなりを使用しますただ廃棄された...の実装/dev/nullカーネルでは、そのようにだけ、より効率的です。また、/dev/nullリダイレクトの代わりに引数として渡したい場合はどうなりますか?(<(...)bashで使用できますが、それはさらに重い方法です!)
フィルブランデン

4
nullリダイレクトを使用する代わりに、という名前のプログラムにパイプする必要がある場合/dev/null、シェルにstderrだけをnullに送信してプログラムを実行するよう指示する簡単で明確な方法はありますか?
マーク・Plotnick

5
これは、オーバーヘッドデモ用の非常に高価なセットアップです。/dev/zero代わりに使用することをお勧めします。
クリリス

20
これらの例は間違っています。dd of=-と呼ばれるファイルへの書き込みは、デフォルトで書き込む場所であるstdoutへの書き込みを-省略します。配管へと動作しないでしょうその標準入力を読んでいないので、SIGPIPEで殺されるでしょう。入力を破棄するコマンドには、...を使用できます。また、ボトルネックとしておそらく関係のない比較は、おそらくここでの乱数生成でしょう。of=ddfalsefalseddcat > /dev/null
ステファンシャゼラス

8
などのASTバージョンはdd、宛先が/ dev / nullであることを検出しても、書き込みsyscallを実行しません。
マークプロトニック

54

私は、Unix(およびその結果としてLinux)を形作ったビジョン/設計に多くの理由があるのではないかと考えています。

間違いなく、余分なプロセスを回転させないことでパフォーマンスが無視できないほど向上することは間違いありませんが、それ以上のことがあると思います。シェルスクリプトの観点ではなく、システムの観点から。

あなたが持っていると言うnullコマンドラインプログラム、および/dev/nullデバイスノードを。シェルスクリプティングの観点から見ると、foo | nullプログラムは実際には本当に便利便利であり、入力するfoo >/dev/nullのに少し時間がかかり、奇妙に見えるかもしれません。

ただし、次の2つの演習があります。

  1. null既存のUnixツールと/dev/null-easy:を使用してプログラムを実装しましょうcat >/dev/null。できた

  2. /dev/null面で実装できますnullか?

入力を破棄するだけのCコードは些​​細なことですから、そのタスクで仮想ファイルを使用できることがなぜ有用なのはまだ明らかではないかもしれません。

考えてみてください。ほとんどすべてのプログラミング言語は、ファイル、ファイル記述子、およびファイルパスを操作する必要があります。これらは最初からUnixの「すべてはファイル」パラダイムの一部だったからです。

持っているのがstdoutに書き込むプログラムだけである場合、プログラムは、すべての書き込みを飲み込む仮想ファイルにリダイレクトするか、すべての書き込みを飲み込むプログラムにパイプするかを気にしません。

データの読み取りまたは書き込み(ほとんどのプログラムが行う)のためにファイルパスを取るプログラムがあり、それらのプログラムに「空白入力」または「この出力を破棄する」機能を追加したい場合/dev/nullは、無料で提供されます。

それの優雅さは、関連するすべてのプログラムのコードの複雑さを軽減することに注意してください-システムが実際の「ファイル名」を持つ「ファイル」として提供できる一般的だが特別なユースケースごとに、コードはカスタムコマンドの追加を避けることができます-lineオプションと処理するカスタムコードパス。

優れたソフトウェアエンジニアリングは、問題のいくつかの要素を抽象化するための良いまたは「自然な」メタファーを見つけることに依存することが多く、考えやすくなりますが、柔軟性維持されるため、基本的に同じ範囲の上位レベルの問題を同じ低レベルの問題の解決策を常に再実装することに時間と精神的なエネルギーを費やす。

「すべてはファイルである」リソースにアクセスするための1つのそのような比喩のようです:あなたが呼び出すopenオブジェクトへの参照(ファイルディスクリプタ)を取得し、階層的名前空間内で指定されたパスの、そしてあなたのことができread、およびwriteファイル記述子に、など。stdin / stdout / stderrは、たまたま事前に開かれたファイル記述子でもあります。パイプは単なるファイルとファイル記述子であり、ファイルリダイレクトを使用すると、これらすべての要素を結び付けることができます。

Unixは、これらの抽象化がどれほどうまく機能したかによって、ある程度成功しました/dev/nullが、全体の一部として最もよく理解されています。


PS「すべてはファイル」のUnixバージョン/dev/nullや、その後に続く多くのシステムに実装されているメタファーのより柔軟で強力な一般化に向けた最初のステップとしての価値があります。

たとえば、Unix /dev/nullでは、カーネル自体に実装する必要があるような特殊なファイルのようなオブジェクトが、ファイル/フォルダー形式で機能を公開するのに十分有用であることが判明し、それ以来、プログラムに方法を提供する複数のシステムが作成されましたそれをするために。

最初の1つは、Unixを作ったのと同じ人々によって作られたPlan 9オペレーティングシステムでした。後に、GNU Hurdはその「翻訳機」で同様のことを行いました。その一方で、Linuxは最終的にFUSEを取得しました(これは現在、他の主流システムにも広がっています)。


8
@PeterCordesの答えのポイントは、デザインを理解していないという立場から始まります。誰もがすでに設計を理解していれば、この質問は存在しません。
OrangeDog

1
@mtraceur:ルート権限なしでイメージファイルをマウントしますか?FUSEがルートを必要としないかもしれないといういくつかの証拠を示していますが、私にはわかりません。
ピーター

1
@PeterCordes RE:「奇妙に思えます」:それは設計に対する謝罪ではなく、その下のシステム実装を考えていない場合にどのように見えるかを単に認めているだけで、システムについてまだユーレカの瞬間を持っていませんワイドなデザインの利点。「シェルスクリプトの観点から」その文を開き、数文前のシステムの観点とシステムの観点との対比をほのめかして、そのことを明確にしようとしました。さらに考えてみると、「奇妙に見える」のが良いので、それを微調整します。冗長にすることなく、より明確にするために、さらなる文言の提案を歓迎します。
mtraceur

2
Unixに関して若いエンジニアとして私が最初に言われたのは「Everything Is A File」であり、私はあなたが首都を聞くことができると誓います。そして、その考えを早期に把握することで、Unix / Linuxの理解がはるかに容易になります。Linuxは、その設計哲学のほとんどを継承しました。誰かが言及してくれてうれしいです。
StephenG

2
@ PeterCordes、DOS NULは、すべてのディレクトリにマジックファイル名を表示することで入力の問題を「解決」しました。つまり、入力する必要があるのはのみ> NULです。
クリスチャン・シウピトゥ

15

パフォーマンス上の理由から、プログラムではなくキャラクターデバイス(通常のファイルのように動作する/dev/null)であると思います。

プログラムである場合、プログラムのロード、開始、スケジューリング、実行、およびその後のプログラムの停止とアンロードが必要になります。あなたが説明している単純なCプログラムは、もちろん多くのリソースを消費しませんが、プロセス管理操作は大規模にコストがかかるため、多数(たとえば数百万)のリダイレクト/パイピングアクションを考慮すると、大きな違いを生むと思いますコンテキストスイッチが含まれます。

別の仮定:プログラムにパイピングするには、受信プログラムによってメモリが割り当てられる必要があります(後で破棄された場合でも)。したがって、ツールにパイプすると、送信プログラムで1回、受信プログラムで2回、メモリ消費が2倍になります。


10
セットアップコストだけでなく、パイプへの書き込みごとにメモリコピーと読み取りプログラムへのコンテキストスイッチが必要です。(または、少なくとも、パイプバッファがいっぱいになったときにコンテキストを切り替えます。またread、データを読み込むときに、リーダーは別のコピーを行う必要があります)。これは、Unixが設計されたシングルコアPDP-11では無視できません!メモリ帯域幅/コピーは、今日よりもはるかに安くなりました。writeFDへのシステムコールは、上開き/dev/nullさえバッファからデータを読み出すことなく、すぐに返すことができます。
ピーター

@PeterCordes、私のメモは接線ですが、逆説的に言えば、今日のメモリ書き込みはかつてないほど高価になる可能性があります。8コアCPUは潜在的に1クロック時間で16の整数演算を実行しますが、エンドツーエンドのメモリ書き込みは、たとえば16クロック(4 GHz CPU、250 MHz RAM)で完了します。これが256の要因です。最新のCPUに対するRAMは、PDP-11 CPUに対するRL02のようなもので、周辺記憶装置のようなものです。:)それほど簡単ではありませんが、当然ですが、キャッシュにヒットするものはすべて書き出され、無駄な書き込みは他の計算からこれまでにない重要なキャッシュスペースを奪います。
-kkm

@kkm:はい、カーネルのパイプバッファーとnullプログラムの読み取りバッファーで約2倍の128kiBのL3キャッシュフットプリントを浪費しますが、ほとんどのマルチコアCPUはすべてのコアが常にビジーで実行されません。nullプログラムを実行するCPU時間はほとんど無料です。すべてのコアが固定されたシステムでは、無駄な配管が大事です。しかし、いや、RAMにフラッシュせずに「ホット」バッファを何度も書き換えることができるため、ほとんどの場合、キャッシュではなくL3帯域幅を奪い合っています。特に、同じ物理上の他の論理コア(S)SMT(ハイパースレッディング)システム上で、素晴らしいではありません...競合している
ピーター・コルド

....しかし、メモリの計算には非常に欠陥があります。最近のCPUには多くのメモリ並列性があるため、DRAMへのレイテンシは200〜400コアクロックサイクルおよびL3> 40のようなものですが、帯域幅は1 クロックあたり約8バイトです。(驚いたことに、クアッドチャネルメモリを搭載したメニーコアXeonでは、クアッドコアデスクトップよりも L3またはDRAMへのシングルスレッド帯域幅の方が劣っています。 max_concurrency / latency:シングルスレッドのメモリスループットに関して、SkylakeがBroadwell-Eよりもはるかに優れているのはなぜですか?
Peter Cordes

... クアッドコアと18コアを比較するHaswellの数値については、7-cpu.com / cpu / Haswell.htmlも参照してください。とにかく、はい、現代のCPUは、メモリを待たずに立ち往生していない場合、クロックごとに途方もない量の作業を行うことができます。1993年のPentiumや、最新のローエンドデュアルイシューARMのように、1クロックあたりのALU演算数は2つだけのようです。RyzenまたはHaswellは、潜在的に 4スカラー整数ALU ops + コアあたり1クロックあたり 2メモリops 、またはSIMDを使用してさらに多くを実行します。たとえば、Skylake-AVX512の(コアあたり)2クロックあたりのスループットは、vpaddd zmm命令あたり16個の32ビット要素です。
ピーター

7

「すべてがファイル」であり、したがって他のほとんどの回答が基づいているすべての場所での使いやすさは別として、@ user5626466が言及しているようにパフォーマンスの問題もあります。

実際に示すために、次の簡単なプログラムを作成しますnullread.c

#include <unistd.h>
char buf[1024*1024];
int main() {
        while (read(0, buf, sizeof(buf)) > 0);
}

そしてそれをコンパイルします gcc -O2 -Wall -W nullread.c -o nullread

(注:パイプでlseek(2)を使用することはできません。したがって、パイプを空にする方法は、空になるまでパイプから読み込むことです)。

% time dd if=/dev/zero bs=1M count=5000 |  ./nullread
5242880000 bytes (5,2 GB, 4,9 GiB) copied, 9,33127 s, 562 MB/s
dd if=/dev/zero bs=1M count=5000  0,06s user 5,66s system 61% cpu 9,340 total
./nullread  0,02s user 3,90s system 41% cpu 9,337 total

一方、標準の/dev/nullファイルリダイレクトでは、はるかに優れた速度が得られます(言及されている事実により、コンテキストの切り替えが少なくなり、カーネルはデータをコピーするのではなく無視するなど)。

% time dd if=/dev/zero bs=1M count=5000 > /dev/null
5242880000 bytes (5,2 GB, 4,9 GiB) copied, 1,08947 s, 4,8 GB/s
dd if=/dev/zero bs=1M count=5000 > /dev/null  0,01s user 1,08s system 99% cpu 1,094 total

(これはそこにコメントする必要がありますが、それには大きすぎて完全に読めないでしょう)


どのハードウェアでテストしましたか?Skylake i7-6700k(DDR4-2666)で取得する23GB / sに比べて4.8GB / sはかなり低いですが、バッファはL3キャッシュでホットのままである必要があります。 +メルトダウンの緩和が有効になっています。パイプバッファーが1M未満であるため、パイプに二重のダメージがあり、書き込み/読み取りのシステムコールが多くなります。ただし、パフォーマンスの10倍近くは予想よりも悪いです。 3.3GB / s、x86-64 Linux 4.15.8-1-ARCHを実行しているので、これは6.8倍です。すごい、シ​​ステムコールは今や高価です
Peter Cordes

1
@PeterCordes 3GB / sで64kパイプバッファーを使用すると、1秒あたり2回の103124 syscallsと、その数のコンテキストスイッチが示唆されます。1秒あたり200000 syscallsのサーバーCPUでは、ワーキングセットが非常に少ないため、PTIから最大8%のオーバーヘッドが予想されます。(私が参照しているグラフにはPCID最適化は含まれていませんが、小さなワーキングセットではそれほど重要ではありません)。そこで、PTIが大きな影響を与えるかどうかわかりませんか? brendangregg.com/blog/2018-02-09/...
sourcejedi

1
おもしろいので、2MBのL2キャッシュを備えSilvermontであるため、ddバッファー+受信バッファーが適合しません。おそらく、最終レベルのキャッシュ帯域幅ではなく、メモリ帯域幅を扱っています。512kバッファまたは64kバッファでより良い帯域幅を得ることができます。(によると、strace私のデスクトップ上、writeおよびread< - > 1048576を戻ってきているので、私はそれは私たちが唯一のユーザーに払っていることと思います。ではなく、64Kごとに、一回のMIBあたり@sourcejediをTLB無効のカーネルコスト+分岐予測のフラッシュをそれはスペクターですコストが最も高い緩和策だと思う)
ピーター

1
@sourcejedi:Spectre緩和機能を有効にすると、Spectre緩和機能を有効にしたSkylakeでsyscallすぐに返されるコストは、@ BeeOnRopeのテストによるとENOSYS、ほとんどがwrmsrBPUを無効にします。緩和策を無効にした場合、ユーザー->カーネル->ユーザーのラウンドトリップ時間は約160サイクルです。あなたはしかし、もしされている多くのメモリを触れ、メルトダウンの軽減も重要です。Hugepagesが役立つはずです(TLBエントリを再ロードする必要が少なくなります)。
ピーター

1
@PeterCordesシングルコアUNIXシステムでは、64Kあたり1つのコンテキストスイッチ、またはパイプバッファが何であれ、確かに痛いでしょう...実際には[2つのCPUコアを持つ同じ数のコンテキストスイッチ]も表示されます。 (unix.stackexchange.com/questions/439260/…); また、コンテキストスイッチとして各64kのスリープ/ウェイクサイクルをカウントする必要があります(名目上の「アイドルプロセス」へ)。同じCPUでパイプラインプロセスを維持することは、実際には2倍以上の速度で機能しました。
sourcejedi

6

あなたの質問は、ファイルの代わりにヌルプログラムを使用することで、おそらく簡単に何かが得られるかのように提起されます。おそらく、「魔法のファイル」という概念を取り除き、代わりに「通常のパイプ」だけを持つことができます。

しかし、パイプもファイルだと考えてください。通常は名前が付けられていないため、ファイル記述子を介してのみ操作できます。

このやや不自然な例を考えてみましょう。

$ echo -e 'foo\nbar\nbaz' | grep foo
foo

Bashのプロセス置換を使用して、より遠回りの方法で同じことを実現できます。

$ grep foo <(echo -e 'foo\nbar\nbaz')
foo

grepfor echoを交換すると、カバーの下に表示されます。

$ echo foo <(echo -e 'foo\nbar\nbaz')
foo /dev/fd/63

<(...)構築物を、ただそれだけで名前を付けることを起こる、ファイル名に置き換え、とgrepは、それが任意の古いファイルを開くことだと思っています/dev/fd/63。これ/dev/fdは、アクセスするファイルが所有するすべてのファイル記述子の名前付きパイプを作成する魔法のディレクトリです。

通常のファイルのように、すべてにmkfifo現れる名前付きパイプを作成することで、魔法を減らすことができlsます。

$ mkfifo foofifo
$ ls -l foofifo 
prw-rw-r-- 1 indigo indigo 0 Apr 19 22:01 foofifo
$ grep foo foofifo

他の場所:

$ echo -e 'foo\nbar\nbaz' > foofifo

そして、見よ、grepは出力しますfoo

パイプと通常のファイル、および/ dev / nullなどの特別なファイルはすべて単なるファイルであることに気づいたら、nullプログラムの実装はより複雑になります。カーネルはどちらの方法でもファイルへの書き込みを処理する必要がありますが、/ dev / nullの場合は書き込みを床に落とすことができますが、パイプでは実際にバイトを別のプログラムに転送する必要があります。実際に読んでください。


@Lyle Yeah?それでは、なぜエコー出力されるの/dev/fd/63ですか?
フィルフロスト

ふむ いい視点ね。まあ、これはシェルによって実装されているので、おそらくあなたのシェルは私が育った古いBourneシェルとは異なるでしょう。
ライル

1つの違いは、エコーはstdinから読み取れないのに対し、grepは読み取るが、シェルがそれらを実行する前にそれをどのように知るかは考えられないことです。
ライル

1
そして、straceはこれをより明確にします:私にとって。あなたはそれを正確に持っています、bashで。「<(...)」コンストラクトは、<filenameとはまったく異なる処理を行っています。ふむ 私は何かを学びました。
ライル

0

私は、歴史的なパラダイムとパフォーマンスを超えたセキュリティ問題があると主張します。特権実行資格情報を使用してプログラムの数を制限することは、どんなに単純であっても、システムセキュリティの基本原則です。/dev/nullシステムサービスで使用するため、このような特権を持つためには、必ず交換が必要になります。最新のセキュリティフレームワークは、悪用を防止する優れた機能を果たしますが、絶対確実ではありません。ファイルとしてアクセスされるカーネル駆動デバイスは、悪用するのがはるかに困難です。


これはナンセンスに聞こえます。バグのないカーネルドライバーを記述することは、そのstdinを読み取り+破棄するバグのないプログラムを記述することほど簡単ではありません。それは両方のためになるよう、setuidや何もする必要はありません/dev/nullか提案されている入力-廃棄プログラム、攻撃ベクトルは同じになります:奇妙な何かをするには、rootとして実行するスクリプトまたはプログラムを取得(のようにしてみてくださいlseek/dev/nullまたはオープン同じプロセス、またはIDKから複数回、または/bin/null奇妙な環境で呼び出します。
ピーター

0

他の人が既に指摘したように、/dev/null あるコードの行の少数からなるプログラム。これらのコード行がカーネルの一部であるというだけです。

より明確にするために、Linuxの実装を次に示します。キャラクタデバイスは、読み取りまたは書き込み時に関数を呼び出します。ここで登録されread_nullの呼び出しを読み取りながら、write_nullの/dev/null呼び出しへの書き込み。

文字通り数行のコード:これらの関数は何もしません。読み取りと書き込み以外の機能をカウントする場合にのみ、手の指よりも多くのコード行が必要になります。


たぶん私はそれをもっと正確に表現すべきだった。プログラムではなくcharデバイスとして実装することを意味していました。どちらにしても数行になりますが、プログラムの実装は明らかに単純になります。他の回答が指摘したように、これには多くの利点があります。中でも効率と移植性が重要です。
アンクールS

承知しました。実際の実装を見るのは楽しかったのでこの答えを追加しました(最近自分で発見しました)が、本当の理由は他の人が実際に指摘したことです。
マチューモイ

私も!私は最近のLinuxでデバイスを習い始めと回答は非常に有益だった
はAnkur S

-2

/ dev / chargen / dev / zeroおよび/ dev / nullを含むそれらのような他のものも知っていることを願っています。

LINUX / UNIXにはこれらのいくつかがあります-人々がよく書かれたコードフラグをうまく利用できるように利用可能になっています。

Chargenは、特定の繰り返しパターンの文字を生成するように設計されています-非常に高速で、シリアルデバイスの限界を押し上げ、テストなどで作成および失敗したシリアルプロトコルのデバッグに役立ちます。

ゼロは、既存のファイルを作成するか、ゼロを大量に出力するように設計されています

/ dev / nullは、同じ考えを念頭に置いた別のツールです。

ツールキット内のこれらのツールはすべて、既存のプログラムがデバイスまたはファイルの代替としての(特定のニーズ)に関係なく、独自の何かをするチャンスが半分あることを意味します。

コンテストを設定して、ご使用のLINUXのバージョンの少数のキャラクターデバイスのみを対象に、誰が最もエキサイティングな結果を出すことができるかを確認しましょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.