GNU/Linux >> Linux の 問題 >  >> Linux

Ctrl+C を押すと Linux が常に ^C を出力するのはなぜですか?

^C をインターセプトし、接続されたプロセス (シェル) に送信されるシグナルに変換するのは端末 (ドライバー) です。 stty intr ^B 代わりに ^B をインターセプトするようにターミナル ドライバに指示します。 ^C を端末に返すのも端末ドライバーです。

シェルは、回線の反対側に位置する単なるプロセスであり、端末ドライバー (/dev/ttyX など) を介して端末から stdin を受信し、stdout (および stderr) も同じ tty に接続されます。 .

(エコーが有効になっている場合) 端末はキーストロークを 両方 に送信することに注意してください。 プロセス (グループ) を終了し、端末に戻ります。 stty コマンドは、tty を「制御する」プロセスの tty ドライバー用の ioctl() の単なるラッパーです。

更新:シェルが関与していないことを示すために、次の小さなプログラムを作成しました。 exec ./a.out を介して親シェルで実行する必要があります (とにかく、インタラクティブ シェルはドーター シェルをフォークするようです) プログラムは、SIGINTR を生成するキーを ^B に設定し、エコーをオフに切り替え、標準入力からの入力を待ちます。

#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

int thesignum = 0;
void handler(int signum);

void handler(int signum)
{ thesignum = signum;}

#define THE_KEY 2 /* ^B */

int main(void)
{
int rc;
struct termios mytermios;

rc = tcgetattr(0 , &mytermios);
printf("tcgetattr=%d\n", rc );

mytermios.c_cc[VINTR] = THE_KEY; /* set intr to ^B */
mytermios.c_lflag &= ~ECHO ; /* Dont echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );

printf("Setting handler()\n" );
signal(SIGINT, handler);

printf("entering pause()\n... type something followed by ^%c\n", '@'+THE_KEY );
rc = pause();
printf("Rc=%d: %d(%s), signum=%d\n", rc, errno , strerror(errno), thesignum );

// mytermios.c_cc[VINTR] = 3; /* reset intr to ^C */
mytermios.c_lflag |= ECHO ; /* Do echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );

return 0;
}

intr.sh:

#!/bin/sh
echo $$
exec ./a.out
echo I am back.

シェルは入力したものすべてをエコーするので、 ^C と入力すると 、それもエコーされます(そして、あなたの場合はシグナルハンドラによって傍受されます)。コマンド stty -echo ニーズ/制約によっては、役立つ場合とそうでない場合があります。詳細については、stty の man ページを参照してください。

もちろん、いつでも、より低いレベルでさらに多くのことが行われます 周辺機器デバイス ドライバー (^C 信号の生成に使用するキーボード ドライバーや、すべてを表示するターミナル ドライバーなど) を介してシステムと通信します。アセンブリ/機械語、レジスタ、ルックアップ テーブルなどのレベルでさらに深く掘り下げることができます。より詳細で深いレベルの理解が必要な場合は、以下の本から始めるのが良いでしょう:

The Design of the Unix OS は、この種のものの良い参考資料です。さらに 2 つの古典的なリファレンス:Unix プログラミング環境と UNIX 環境での高度なプログラミング

この SO の質問のすばらしい要約は、どのように Ctrl-C で子プロセスを終了させますか?

"たとえば find のようなプログラムを実行するとき 、シェル:

  • シェルフォークそのもの
  • 子に対してデフォルトのシグナル処理を設定
  • 子を指定されたコマンド (例:find) に置き換えます
  • CTRL-C を押すと、親シェルはこのシグナルを処理しますが、子シェルはそれを受け取り、デフォルトのアクションで終了します。 (子もシグナル処理を実装できます)"

Linux
  1. Pythonモジュールはターミナルでは見つかりませんが、Pythonシェル、Linuxでは見つかりません

  2. 「&」を使用して Linux シェル コマンドを実行するのはなぜですか?

  3. Linux コンソールで、出力をラップしない方法

  1. Linuxターミナルとシェルをクリスマス化する方法

  2. シェルコマンド置換が末尾の改行文字を飲み込むのはなぜですか?

  3. ss - Linux ソケット統計ユーティリティの出力形式

  1. Linux のシェル出力を HTML に変換するには?

  2. 色付きのテキストを Linux 端末に出力するにはどうすればよいですか?

  3. このシェル パイプラインが終了するのはなぜですか?