Ctrl-D(EOF)がシェルを終了するのはなぜですか?


69

このエスケープシーケンスを入力することにより、文字通り「ファイルを終了する」のですか、つまり、対話型のシェルセッションは、他のファイルストリームのように、シェルによって実際のファイルストリームとして表示されますか?ある場合、どのファイルですか?

または、Ctrl+ Dシグナルは単なるプレースホルダーであり、「ユーザーは入力の提供を終了し、終了してもよい」という意味ですか?



6
参考までに、bashでset -o ignoreeofその動作を変更することができます。
キース14年

同じ問題がありました。私のエラーは、誤ってkonsoleプロファイルのショートカットを「Ctrl + d」に割り当てたことです。私の最も誇らしい瞬間ではありません。
ブライアンシモンセン

回答:


79

^D(としても知られている文字\04、または0x4の送信の終了 Unicodeでは)のデフォルト値であるeofカーネルの特殊制御文字端末のパラメータまたは疑似端末ドライバ(より正確にのttyシリアルまたは擬似に取り付けられたラインの規律ttyデバイス)。それはだc_cc[VEOF]termiosTCSETS / TCGETSに渡される構造ioctlドライバーの動作に影響を与えるために端末装置に1の問題。

それらを送信する典型的なコマンドioctlssttyコマンドです。

すべてのパラメーターを取得するには:

$ stty -a
速度38400ボー。行58; 列191; line = 0;
intr = ^ C; quit = ^ \; 消去= ^ ?; kill = ^ U; eof = ^ D ; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^ Q; stop = ^ S; susp = ^ Z; rprnt = ^ R; werase = ^ W; lnext = ^ V; flush = ^ O;
最小= 1; 時間= 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

このeofパラメータは、端末デバイスがicanonモードにある場合にのみ関係します。

そのモードでは、ターミナルドライバー(ターミナルエミュレーターではない)が非常に単純なラインエディターを実装します。このエディターではBackspace、文字Ctrl-Uを消去したり、行全体を消去したりできます。アプリケーションがターミナルデバイスから読み取ると、あなたは押しReturnた時点でread()返します最後を含むフルラインLF文字(デフォルトでは、端末ドライバはまた、翻訳CR時に端末によって送信さReturnLF)。

ここで、を押さずにこれまでに入力した内容を送信する場合Enterは、eof文字を入力できます。ターミナルエミュレータからその文字を受け取ると、ターミナルドライバは行の現在のコンテンツを送信し、そのread上でそれを行うアプリケーションはそのまま受信します(そして、末尾のLF文字は含まれません)。

現在、現在の行が空で、アプリケーションが以前に入力された行を完全に読み取る場合、read0文字が返されます。

これは、アプリケーションに対してファイルの終わりを意味します(ファイルから読み取る場合、読み取るものがなくなるまで読み取ります)。それがeof文字と呼ばれる理由です。これを送信すると、アプリケーションはこれ以上入力が利用できないことを確認するからです。

現在、最新のシェルは、プロンプトでターミナルをicanonモードに設定しません。これは、ターミナルドライバーに組み込まれているものよりもはるかに高度な独自のラインエディターを実装しているためです。ただし、独自のラインエディターでは、ユーザーの混乱を避けるために、^Dキャラクター(または端末のeof設定が何であれ)に同じ意味を与えます(意味しますeof)。


このコメントを読み始めたとき、それがステファンによって書かれていることを知った:)あなた、ステファンは私のバッシュのヒーローであり、私は皮肉ではありません。NYCにいるなら、私はあなたと昼食を食べて、あなたの脳を選びたいです、私は買っています。
グレッグレベンタール

@GreggLeventhal。ありがとう。でも、すぐにニューヨークに行く可能性は非常に低いです。
ステファンシャゼラス

7ビットASCIIでもEOTです
Bananguin

9

CTRL_Dは、これがテキストストリームの終わりであることを示す単なる信号です。それでファイルを終了するのではなく、入力して入力ストリームを終了します。また、CTRL_Dは、hexdumpツールで確認できるように、文字やバイトを表しません。

# cat >test.txt
asdf# hexdump -C test.txt 
00000000  61 73 64 66                                       |asdf|
00000004
# ll test.txt 
-rw-r--r-- 1 root root 4 Jan 21 11:55 test.txt

5
そして、シェルが終了する理由は、シェルは基本的に入力を受け入れて処理を行うプロセスだからです。これ以上入力が来ないことを伝えると、シェルが行うことはこれ以上ありません。
ジェニーD 14年

EOFシーケンスは、たとえばテキストファイルに含まれておらず、OSによって生成され、読み取るデータがもうないことを報告します。私が本当に求めているのは、他のファイルストリームのように、シェルから対話型ターミナルセッションが実際のファイルストリームとして見られるかどうかだと思います。
ゲーブ14年

元の質問を編集して、明確にしました。
ゲーブ14年

2
はい、bashに送られるストリームは他の入力ストリームです。CTRL_Dは、入力ストリームが終了し、bashを終了できることを通知します。
トールステンスターク14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.