シェルで制御文字(^ C、^ D、^ [、...)をさまざまな方法で表示する方法

シェルで制御文字(^ C、^ D、^ [、...)をさまざまな方法で表示する方法

シェルに制御文字を入力すると、「キャレット」という文字を使用して表示されます。たとえば、エスケープ^[文字はカラットで作成されます。

私はbashシェルをカスタマイズし、素敵に見えるようにするのが好きです。例えば、私は私のものを変えてPS1華やかPS2に変わりました。今、制御キャラクターも一般キャラクターと簡単に区別できるようにユニークな形を持つようになることを願っています。

$ # Here I type CTRL-C to abort the command.
$ blahblah^C
          ^^ I want these two characters to be displayed differently

シェル強調制御文字を異なるようにする方法はありますか?

太字で表示したり、プレーンテキストとは異なる色で表示したりできますか?

使っています強く打つbashこれにはシェルがありますが、さまざまなシェルで動作するソリューションがある可能性があるため、質問は表示されませんでした。

ノート制御文字の強調がどのレベルで発生するかわかりません。私は最初にそれが殻自体にあると思いました。今はそうだと聞いた読書船たとえば、制御文字がシェルに表示される方法を制御します。強く打つ。だからこの質問は今タグ付けされ、readline私はまだ答えを探しています。

答え1

を押すと、Ctrl+Xターミナルエミュレータは疑似ターミナルペアのベース側にバイト0x18を書き込みます。

次のことは、ttyラインルール(マスター(エミュレータの制御下にある)とスレーブ(ターミナルで実行されているアプリケーションが対話する)の間にあるカーネルのソフトウェアモジュール)がどのように構成されるかによって異なります。

構成するコマンドttyライン規律それはstty命令です。

このような愚かなことは、アプリケーションの実行時にcat標準入力が端末(デフォルト)であるかどうかを知らないか気にしません。モデルttyライン規約はおおよそのパターンを実装します。ラインエディタ

一部の対話型アプリケーションでは、単純なもの以上が必要です。ラインエディタ起動時にこれらの設定を変更し、シャットダウン時に復元するのが一般的です。現代のシェル、彼らの指示に従ってそのようなアプリケーションの例です。彼らは独自の高度なラインエディタを実装しました。

通常、コマンドラインを入力すると、シェルはttyラインルールをこのモードに設定し、Enterキーを押して現在のコマンドを実行すると、シェルは通常のttyモードに戻ります(プロンプトが実行される前に適用されたかのように)。

コマンドを実行すると、現在stty -a使用されている設定が表示されます。愚かなアプリicanonと設定echoが有効になっていることがわかりますechoctl

これは次のことを意味します。

  • icanon:おおよその線エディタが有効になります。
  • echo:入力した文字(ターミナルエミュレータがマスターに書き込む文字)はエコリターン(ターミナルエミュレータで読み取ることができます)
  • echoctl:代わりにエコAsisでは、制御文字は次のようになります。エコのように^X

と入力するとしますA B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return

端末エミュレータは以下を送信しますAB\bC\x18\b\r。ライン規律はエコback:、AB\b \bC^X\b \b\b \b\r\nスレーブ側()から入力を読み取るアプリケーションは/dev/pts/xを読みますAC\n

アプリケーションが見るものはすべてでAC\n、 を押したときにのみ表示できるので、そこの出力を制御することEnterはできません。^X

あなたはそれに気づくでしょうエコ、最初の項目^H^?一部の端末の場合は設定を参照)が端末に送信されeraseます。\b \bこれはカーソルを後ろに移動し、空白で覆い、再びカーソルを後ろに移動する順序で、2番目の結果^H\b \b\b \b2文字を削除すること^ですX

(0x18)自体が出力^Xに変換されます。同様にバックスペースで削除したため、アプリには入っていません。^XB

\r(別名)はエコーの場合()、アプリケーションの場合()^Mに翻訳されます。\r\n^M^J\n^J

それでは、これらの人々のための私たちの選択は何ですか?無音アプリケーション:

  • 障害を負うechostty -echo)。これは何もエコーしないことによって制御文字がエコーされる方法を効果的に変更します。実際の解決策ではありません。
  • 障害のあるechoctl。これは、制御文字(^H^M...、および行エディタで使用される他のすべての文字を除く)がエコーされる方法を変更します。それから彼らエコそのまま。つまり、たとえば、ESC文字は\e^[/ 0x1b)バイト(ターミナルでエスケープシーケンスの始まりとして認識されます)として送信され、(BEL、端末でビープ音が鳴ります)^Gを送信すると...\aオプション。
  • 太い線エディタ(stty -icanon)を無効にします。元のアプリケーションの有用性が大幅に削減されるため、これは実際にはオプションではありません。
  • カーネルコードを編集してttyラインルールの動作を変更し、次の手順を実行します。エコ\e[7m^X\e[m単に送信するのではなく、文字転送を制御します^X\e[7m逆方向ビデオは通常、ほとんどの端末でここで有効になります)。

1つのオプションは、愚かなアプリケーションにクールな行エディタを追加するこのようなラッパーを使用することですrlwrap。これは汚いハッキングです。このラッパーは、実際にはread()端末装置の単純なsをreadline行エディターの呼び出しに置き換えようとします(tty行規則のモードを変更します)。

さらに一歩進んで、次の解決策を試すこともできます。これGNU画面の機能を使用して端末のすべての入力をハイジャックしてzshのラインエディタを通過します(^X逆方向ビデオでsが強調表示されます)。:exec

これで、独自のラインエディタを実装するアプリケーションの場合、どのようにメソッドを決定するかはアプリケーションに依存します。エコもう終わりました。bashカスタム制御文字エコー方法をサポートしない関数を実装するには、readline を使用します。

については、zsh以下を参照してください。

info --index-search='highlighting, special characters' zsh

zsh印刷できない文字はデフォルトで強調表示されます。次のように強調表示をカスタマイズできます。

zle_highlight=(special:fg=white,bg=red)

その特殊文字の場合、赤の背景に白いテキストが強調表示されます。

ただし、これらの文字のテキスト表現はカスタマイズできません。

^XUTF-8ロケールでは、0x18は、、\u378\U7fffffff割り当てられていない2つのUnicodeコードポイント)として、、<0378>(印刷できないUnicode文字)としてレンダリングされます。<7FFFFFFF>\u200b<200B>

\x80iso8859-1ロケールでは... etcでレンダリングされます^�

答え2

私は通常、.bashrcファイルに次のコードを含めます。

function get_exit_status()
{
        local code=$?
        if [ $code -ne 0 ]
        then
                printf $'\001\033[31m\002'"($code)"$'\001\033[0m\002'" "
        fi
}

その後、PS1はこの関数を呼び出します。

PS1='\u@\h \w $(get_exit_status)'

これにより、^ Cを押すとプロンプトに表示されます。

I@mycomputer ~ ^C
I@mycomputer ~ (130)

「0」以外のすべての終了ステータスコードが表示されます。

関連情報