Ccで終了できないのはなぜですか?


20

ed最小限のテキストエディタであるプログラムは、Ctrl- を使用して割り込みを送信しても終了できませんC。代わりにエラーメッセージ「?」を出力します。コンソールに。ed割り込みを受信したときに終了しないのはなぜですか?ここで、単に終了するよりも不可解なエラーメッセージが役立つ理由はありません。この動作により、多くの新規ユーザーが次のような相互作用につながります。

$ ed
hello
?
help
?
exit
?
quit
?
^C
?
^C
?
?
?
^D
$ su
# rm -f /bin/ed

このような悲劇的な浪費は、ed単に中断することに同意すれば簡単に回避できます。

同様の動作を示す別の頑固なプログラムはless、無視する理由があまりないようC-cです。これらのプログラムは単にヒントをとらないのですか?


4
対話型アプリケーションは非対話型と同じではありません。慣れているCtrl-Cの動作は、非対話型のデフォルトです。インタラクティブなものは、独自の目的でCtrl-Cの動作をオーバーライドできます。
jw013 14

4
また、わからない場合は冗談
jw013

@ jw013はい、「典型的なセッション」は冗談でした(何らかの理由でそれを見つけることができませんでした)が、私の質問は深刻です。私が理解していないのはこれらのアプリケーションが実際に有用なものを何も提供しない場合、Ctrl-Cの動作をオーバーライドすることを選択する理由です。
リリーチョン14

1
この質問は「Googleを終了する方法」に対する上位のGoogle検索の回答として表示されるため、ここでは「q」の後にリターンを追加するだけです。多くのボサンは私たちにこの情報をもたらすために死にました。
ドミトリ

回答:


19

Ctrl+ SIGINTをC送信します。SIGINTの従来のアクションは、プログラムのトップレベルループに戻り、現在のコマンドをキャンセルして、プログラムが次のコマンドを待機するモードに入ることです。非対話型プログラムのみがSIGINTで終了することになっています。

したがって、Ctrl+ Cがedを強制終了せず、トップレベルループに戻るのは当然です。Ctrl+ Cは、現在の入力行を中止し、edプロンプトに戻ります。

以下は同じです:Ctrl+ C現在のコマンドを中断し、コマンドプロンプトに戻ります。

歴史的な理由により、edはSIGQUITCtrl+ \)を無視します。通常のアプリケーションは、この信号をキャッチせず、コアダンプを有効にして、自分自身を終了させる必要があります。


@Kzqaiいいえ、通常のアプリケーションはSIGQUITをキャッチすべきでありません。これは非常口を意味します。
ジル 'SO-悪であるのをやめる'

ああ、落とした。よし、引っ込めた。
クズカイ

18

UnixのV7のed(1)ソースコードは、わずか数コメント付きプリミティブ1,762ラインCプログラム、この高啓発ヘッダコメントとなっているものです。

/*
 * Editor
 */

ソースコード自体には根拠がないため、プログラムの作成者から入手するだけです。

edもともと書かれたアセンブリPDP-11にケン・トンプソンによって、しかし、あなたが実際にしているかもしれないC.に移植誰に話をする必要があると思いデニス・リッチー氏は、UNIX用のCを作成しているため、およびCにを使用し、多くの一つでしたUnixを非PDPマシンに移植可能にします。しかし、リッチー博士はもはやそのような質問に答えることができません。

コードを読んだところ、編集されたドキュメントのインコアコピーの内容を保存しようとしたことが示唆されました。他のテキストエディタも停止しないことに気付くでしょうCtrl-C

ここに何edがありますCtrl-C

onintr()
{
    signal(SIGINT, onintr);
    putchr('\n');
    lastc = '\n';
    error(Q);
}

(はい、K& RC。steenkin '戻り値型指定子またはパラメーター宣言は必要ありません。)

英語に翻訳、ed

  1. シグナルハンドラを再登録します。

    (Unixは、1980年代半ばに4.3BSDまで自動リセット信号を受け取りませんでした。)

  2. 新しい行を書き出し、グローバル変数を介してそれを行ったことを記憶しますlastc

    ed.c60個のグローバル変数があります。)

  3. 呼び出しerror()機能、有名プリントより少し行い?、ユーザの視点からは、。

言い換えれば、「あなたは本当にそうするつもりはなかったのですか?」と言っています。


2
また、多くのテキストエディターはControl-Cで終了しないことに注意してください。Vimもそうではありません。nanoも同様です。emacsもそうだとは思いませんが、テストのためにインストールしていません。
デロバート14

3
@derobert Viは、Ctrl + CをUnixのように扱います。トップレベルに戻ります。Emacsには独自のキーバインドがあります。これは、Unixを起源としないためです。UnixのCtrl + Cに相当するEmacsはCtrl + G(ベル文字—コンピューターでベルを鳴らして中断します)
ジル「SO-停止する悪」14

@デロバート:フェアポイント。これを答えに追加しました。
ウォーレンヤング14

2
@Gilles:呼び出しの副作用の一つerror(s)には、ed.cメインの処理ループに戻ることです。longjmp()呼び出しでそうします。震え
ウォーレンヤング

1
詳細と歴史のレッスンをありがとう。これは素晴らしい読み物でした!
-alichaudry

7

ed、他の対話型プログラムと同様に、Ctrl+ Cを使用してプログラム自体のタスクを中断します。
これは、シェルで実行中のタスク(コマンド)を中断する通常の場合と非常に似ています。

ユーザーの観点からは、両方のバリアントは非常に似ています。シグナルの処理は異なります。通常の場合、シグナルSIGINTはフォアグラウンドプロセス、実行中のコマンドに送信され、コマンドは終了することで処理します。
の場合ed、シグナルはedインスタンスであるフォアグラウンドプロセスに送信されます。で実行中のタスクがある場合、タスクedは中断され、プロンプトが表示されます。実行中のタスクがない場合、何も変更されません。

シェルと同様に、シェルもCtrl+ Cで終了しないことに注意してくださいed。そして、それはCtrl+で終了しDます。繰り返しますがed


3

ed気にする3つのシグナルがあります:

  1. INT
  2. HUP
  3. QUIT

POSIX仕様でedは、これらについて次のよう述べています。

SIGINT

edユーティリティは、現在の活動を中断した文字列を記述しなければなら?\n標準出力に、そして(拡張機能説明の項を参照)、コマンドモードに戻ります。

SIGHUP

バッファが空でなく、最後の書き込み以降に変更された場合、edユーティリティはバッファにファイルのコピーを書き込もうとします。まず、ed.hup現在のディレクトリで指定されたファイルが使用されます。それが失敗した場合、環境変数でed.hup指定されたディレクトリで指定されたファイルHOMEが使用されます。いずれの場合でも、edユーティリティは、現在記憶されているパス名にファイルを書き込むことなく、コマンドモードに戻ることなく終了します。

SIGQUIT

edユーティリティは、このイベントを無視しなければなりません。

したがって、どの実装をed使用していても、INTシグナル(Ctrl+C送信するもの)に関してPOSIX仕様に準拠しています。

この点で、エディターは対話型シェルのように動作し、INTシグナルを受信して​​も終了しません。などの他のエディタ、vinano同じことを行います。


1
一部のプログラムの実装は意図的にPOSIXと矛盾しているため、この場合の標準の理論的根拠/それを破るコストを説明することが役立つ場合があります。stackoverflow.com/questions/38605463/…–
sourcejedi

1
@sourcejedi規格では、その根拠にある信号については何も言及していません。私が入手可能な情報源で標準が守られている理由については、何も述べていないed。シェルと同様の動作をしますが、シェルはINT信号を受信して​​も終了しません。
クサラナナンダ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.