新しいファイルを作成するためにコマンドを使用するためのヒントを学びましたcat
。私がテストしたところ、最後の行の後に改行文字がない場合は、ctrl+d次のように2回入力して入力を完了します。
[root@192 ~]# 猫 > テスト ㅏ 第二 ctrl+d[root@192 ~]# 猫 > テスト ㅏ b ctrl+dctrl+d[ルート@192〜]#
これが期待されるか。なぜこのような問題が発生しますか?
答え1
はい、予想されます。
Ctrl-Dがcat
入力で「ファイルの終わり」をチェックし、読み込みを中止して終了すると言いますが、そうではありません。これは端末にあるため、実際の「終了」はなく、実際には「ファイルの終わり」ではありません。一度検出されましたが、read()
0バイトはありません。
通常、read()
システムコールは、ファイルの終わりなど、使用可能なバイトがないことが確認されない限り、ゼロバイトを返しません。利用可能なデータがないネットワークソケットから読み取ると、新しいデータがある時点に到着すると予想されるため、システムコールはゼロバイトを読み取るのではなくブロックし、一部のデータが到着するのを待つか防止するというエラーを返します。接続が閉じると0バイトを返します。その後、ファイルでも最後の(または過去の)読み取りが無限に最終的ではありません。これは、他のプロセスがファイルに何かを書き込んでファイルを長くすることを可能にし、その後新しい読み込み試行がより多くのデータを返す可能性があるためです。 (これは単純な実装tail -f
が行うことです。)
多くのユースケースでは、「0バイトの読み取り」を「ファイルの終わりが検出された」と考えることは、実際には同じと見なされるのに十分にうまく機能します。
ここでCtrl-Dがすることは、端末ドライバに完全な行ではなくても、これまで与えられたすべてを渡すように指示することです。行の先頭では、すべてのゼロバイトはEOFとして検出されます。ただし、文字の後にb
最初のCtrl-Dが送信され、b
0バイトが入力された後、次の文字が送信され、b
EOFとして検出されます。
cat
リダイレクトなしで実行すると、何が起こるかを確認することもできます。私がイタリック体で入力した内容は次のとおりです。
$猫 金持ちCtrl-D金持ち
Ctrl-D を押すとcat
入力を受け取り、foo
再度印刷して入力を待ち続けます。行は次のようになり、foofoo
その後に改行文字がないため、カーソルは最後に残ります。
答え2
ほんの少しだけ言ってください。
私の知る限り、簡単に見るとソースコード、cat
バッファを使用してワークフローを最適化します。cat
特別なコマンドラインオプションなしで標準入力で簡単な呼び出し動作を参照すると、次のようになります。
- バッファが空の場合は、1 つだけCtrl+Dで終了できます。
- そうでない場合、最初の必須 Ctrl-D バッファダンプ(空)、2番目は終了コマンドとして解釈されます。
つまり、実行してcat> test
単に入力すると、 Ctrl-D 現在のディレクトリに空のファイル(名前付き)が作成されたtest
場合、またはファイルがすでに存在する場合は、2番目のファイルを必要とせずに空になります Ctrl-D 。
この質問の範囲外ですが、それほど遠くはありません。ターミナル/シェルインスタンスに文字を送信すると、不要な2番目の結果が不要Ctrl-Dなシャットダウンを引き起こす可能性があります(主に上記の例に関連しています)。