
次の2つのテストファイルがあります。
test1 test2
どちらも空です。次に、次のコマンドを実行します。
$ cat > test1
Enter
This is a test file
Enter
Ctrl+D
$ cat > test2
Enter
This is another test file
Enter
^C
Ctrl+C
$
次に、両方のファイルの内容を確認します。
$ cat test1
This is a test file
$ cat test2
This is another test file
$
それでは、上記の2つの方法を使用して同じ結果を得ると、結果に実際の違いはありますか?
答え1
コマンドが実行されると、cat
端末は標準入力モード。簡単に言えばターミナルという意味だ。ライン規律行編集処理とすべての回答特殊文字ターミナル構成(コマンドを通じて確認および設定可能stty
)
このコマンドは、呼び出しが読み取ったゼロバイトを返すまで、標準入力からcat
単にpingを送信します(これはファイルの終わりを押すPOSIXルールです)。read()
read()
端末には実際の「終了」はありません。ただし、read()
端末装置がゼロバイトを返すことがあります。行規則が「EOF」特殊文字を受け取ると、その時点でread()
構成された内容に関係なく、その時点で編集バッファーにあったすべての内容が返されます。編集バッファが空の場合、読み取られたゼロバイトが返され、終了read()
します。cat
cat
また、基本動作がプロセスを終了する信号に応答して終了する。ラインフィールドはまた、特殊文字に応答して信号を生成します。 「INTR」および「QUIT」特殊文字は、対応するプロセスを含むフォアグラウンドプロセス(グループ)に信号が送信されるようにしますINT
。これらの信号の基本的な作業はプロセスを終了することです。QUIT
cat
cat
これにより観察可能な差が生じる。
- Ctrl+Dこの動作はEOT特殊文字の場合にのみ発生します。これは通常そうですが、そうではありません。〜しなければならないケース。また、Ctrl+はCINTR特殊文字の場合にのみ機能します。
- Ctrl+は、その時点で行が実際に空でない場合はD終了を引き起こしません。ただし、+ は
cat
割り込みを発生します。CtrlC cat
Cの簡単な実装は、質問に示されているようにファイルを指すことが見つかった場合にバッファリングされたstdoutを防ぎます。理論的に終了すると、バッファリングされているがまだcat
出力されていない行が失われる可能性がありますSIGINT
。実際、BSDおよびGNU Cライブラリは、CまたはC ++言語標準で説明されていないバッファリングモードを実装しています。ファイルまたはパイプにリダイレクトされるときの標準出力は次のとおりです。スマートバッファリング。 Cライブラリが
read()
ターミナルデバイスで開いているファイル記述子から新しい行を開始しようとするたびに標準出力をフラッシュすることを除いて、ブロックバッファリングされます。 (厳密に言えば、BSDとGNU Cライブラリはまったく同じ意味を実装せずにそれ以上を実行しますが、この動作は共通のサブセットです)cat
。失われた。 Cライブラリ。- もちろん、
cat
コマンドパイプラインの一部である場合その他cat
プロセスは、データが出力ファイルに到達する前にダウンストリームにバッファリングできます。したがって、ラインルールがSIGINT
パイプライン内のすべてのプロセスを終了するように送信すると(デフォルトでは)バッファリングされているがまだ書き込まれていない入力データは失われますが、cat
「EOF」特殊文字を使用して正常に終了すると、パイプラインはすべてのデータと共に正常に終了します。以前はダウンストリームプロセスに渡されましたそれEOFコマンドの受信それread()
標準入力です。
これは、対話型シェルが入力行を読み取るときに発生するものとほとんど関係がありません。シェルが入力を待っている間、端末は非標準入力モード、どのモードライン分野でしないでください特殊文字を特別に処理します。シェルがCtrl+DおよびCtrl+ を処理する方法Cは、完全にシェルが使用する入力編集ライブラリ (libedit、readline または ZLE) と、その編集ライブラリの構成方法 (キーバインディングなどを使用) によって異なります。
追加読書
- POSIX端末インターフェース。ウィキペディア。
答え2
CTRL+C は割り込み信号です。コマンドが停止します。
CTRL+Dはファイルの終わりです。 + をexit()
入力すると、ファイルの終了によりコマンドが終了します。シェルに+を入力すると、何も起こりません。ただし、+ を入力すると、ほとんどのシステムで現在のシェルが終了します。CTRLDCTRLCCTRlD