私は次のようにシェルキーバインディングを定義しました~/.bashrc
。
bind -x '"\e\C-w":"/usr/bin/reset"'
これにより実行ファイルがCtrl-Alt-w
起動しますreset
。ただし、ターミナルはEnterキーを押すのと同様のままですCtrl-v
。たとえば、この方法でリセットしてすぐにキーを押すと、ショートカットアクションCtrl-p
(前のコマンドの繰り返し)を呼び出す代わりに^P
印刷されます。
この問題の原因と解決策をご存知ですか?
編集する:私がやろうとしていることを再現するPythonプログラムを添付しましたreset
。マルチスレッドアプリケーションをデバッグすると、この状況が頻繁に発生します。
import pdb, thread, time
def interrupt():
time.sleep(2)
pdb.set_trace()
thread.start_new_thread(interrupt, ())
raw_input('? ')
pdb.set_trace()
混乱した状況を再現するには、上記のコードを実行し、デバッガが呼び出されるのを見るためにEnterキーを押します(プログラムを実行してから約2秒後、最後に多くのテキストが印刷され、初期プロンプトが表示されます)。
答え1
実行するとreset
ターミナル表示がクリアされ、すべての入力設定がデフォルト値にリセットされます。特に、入力モードを次に設定します。料理つまり、端末は一度に 1 行を読み込み、ライン全体をアプリケーション (ここではアプリケーションは bash) に送信します。ターミナルのラインエディタはバックスペースキーだけを理解する非常に原始的なエディタであり、素晴らしい機能はありません。 Bashはターミナルを生モードにし、各文字を入力するとすぐにアプリケーションに送信される洗練されたラインエディタを提供します。
ターミナルが混乱している場合(ラインバージョンがないか、bashプロンプトにエコーがない)、回復する最も簡単な方法はコマンドを実行するか、またはreset
実行stty sane
することですReturn。これがうまくいかない場合(たとえば、端末がクッキングモードにあり、行送信文字がデフォルト文字ではないため)reset 2>/dev/pts/42
(端末の再初期化)またはstty sane </dev/pts/42
(入力設定の再初期化)を実行できます(他のリダイレクトを参照)。/dev/pts/42
シェルを実行する端末はどこですか?端末名でコマンドを実行できない場合は、端末名を見つけるために推測が必要な場合があります。端末内でこのコマンドをtty
実行すると表示されます。出力に正しいbashプロセスがある場合は、前に付いた対応する列がps
必要です。TTY
/dev
bashプロンプトに入力してこれらのコマンドを実行することは正確ですが、readlineマクロの一部として実行するわけではありません。 Bashは新しいプロンプトを印刷するたびにターミナル設定をリセットするため、行の編集中に行った操作は後続のコマンドに保持されません。
また、行編集中に実行した場合にbashが依存するパラメータを混乱させますreset
。特に、ターミナルモードを「cooked」に設定しますが、bash行編集では、行エディタは入力文字を文字ごとに受け取る必要があります。 bashコマンドラインバージョンのbashプロンプトの途中と外部の出力を比較してみると、stty
次のような設定が必要だと思います。
bind -x '"\e\C-w": "reset; stty -icrnl -icanon -echo </dev/tty"'
reset
画面を消去しようとする場合は、代わりに電話してください。tput rs1 rs2 rs3 rf
reset
上記のように端末設定をリセットする正しい方法は、reset
bashプロンプトで実行することです。 bashが次のプロンプトを表示すると、古いアプリケーション(ターミナル設定を台無しにしたアプリケーション)が残った設定を復元するため、キーバインディングの一部として実行すると機能しません。 Bashには端末設定を通常のデフォルトにリセットする組み込み機能がないと思いますが、必要に応じてユーザー設定で実行して次の行を使用できます.bashrc
。
PROMPT_COMMAND="$PROMPT_COMMAND
stty sane"
行編集中に端末設定をリセットするキーバインディングが本当に必要な場合は、より洗練されたものが必要です。 bashreset
にプロンプト (編集コマンドの一部ではない) からコマンドを実行させ、現在の編集を再開します。バインディングはreadlineマクロまたはbash関数のみが可能であり、これらの2つを混在させることはできないため、bashではこれを行うのは簡単ではありません。次のコードは++をreadlineマクロCtrlにバインドします。このマクロはバインディングを介してbash関数を呼び出し、バインディングを介してreadline関数を呼び出してから、別のバインディングを介して別のbash関数を呼び出します。これMetaWaccept-line
\C-m
bind -x
バインディングは、長さ1または2のキーシーケンスにのみ割り当てることができます。C-x LETTER
だから、私はほとんど使用されていないヘルパーマクロの組み合わせを使用します。
run_command_during_line_edition () {
saved_READLINE_LINE=$READLINE_LINE saved_READLINE_POINT=$READLINE_POINT
READLINE_POINT=0 READLINE_LINE=" $1"
unset run_command_first
}
restore_saved_command () {
READLINE_LINE=$saved_READLINE_LINE READLINE_POINT=$saved_READLINE_POINT
unset saved_READLINE_LINE saved_READLINE_POINT
}
bind -x '"\C-xZ": "restore_saved_command"'
bind -x '"\C-xR": "reset; stty sane -icrnl -icanon -echo; run_command_during_line_edition reset"'
bind '"\e\C-w": "\C-xR\r\C-xZ"'
繰り返しますが、おそらくこのすべての複雑さは必要ありません。reset
プロンプトでブラインドタイピングをしたりstty sane
に含めるとPROMPT_COMMAND
便利です。ああ、それともzshに切り替えるととても簡単です。