web-dev-qa-db-ja.com

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

このエスケープシーケンスを入力して、文字どおり「ファイルを終了」していますか。つまり、インタラクティブシェルセッションは、他のファイルストリームと同様に、シェルによって実際のファイルストリームとして表示されますか?もしそうなら、どのファイル?

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

72
Geeb

_^D_文字(Unicodeでは_\04_または0x4、 END OF TRANSMISSION とも呼ばれます)は、端末または疑似端末のeof特殊制御文字パラメーターのデフォルト値です。カーネル内のドライバー(より正確には、シリアルまたは疑似ttyデバイスに接続されている tty行の分野 )。これは、TCSETS/TCGETS termiosに渡されるioctl構造体の_c_cc[VEOF]_であり、ドライバーの動作に影響を与えるために端末デバイスに発行します。

これらのioctlsを送信する一般的なコマンドは、sttyコマンドです。

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

 $ stty -a 
 speed 38400 baud;行58;列191;行= 0; 
 intr = ^ C;終了= ^ \;消去= ^ ?; kill = ^ U; eof = ^ D; eol = <undef>; eol2 = <undef>; swtch = <undef>;開始= ^ Q;停止= ^ S; susp = ^ Z; rprnt = ^ R; werase = ^ W; lnext = ^ V;フラッシュ= ^ 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も変換します Return LFに)。

ここで、これまでに入力した内容を送信せずに、 Enter、ここにeof文字を入力できます。端末エミュレーターからその文字を受信すると、端末ドライバーは行の現在の内容を送信します。これにより、readを実行するアプリケーションがそれを受信します。そのままです(また、末尾のLF文字は含まれません)。

現在、現在の行が空で、アプリケーションが以前に入力された行を完全に読み取っていれば、readは0文字を返します。

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

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

81

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
9
Thorsten Staerk