6

このビデオで気づいたのですが、ターミナル プロンプトは新しい行に分割される前に、ターミナルの幅全体に広がっています。PS1このユーザーが行ったように、変数を設定して残りの端末スペースを文字で埋めるにはどうすればよいですか?

PS1問題は、コマンドごとに変数を更新する方法がわからないことです。ファイルが一度だけ読み込まれるのと同じように、の文字列値PS1は一度だけ読み込まれるように思えます。.bashrc各コマンドなどの後に何らかのフックを書く必要がありますか?

PS1また、変数は、それを構成するエスケープ文字に基づいて異なる長さに評価されることも指摘しておく必要があります。たとえば\w、パスを出力します。

を使用して端末の幅を取得し、 を使用し$(COLUMNS)て現在のPS1変数の幅を取得${#PS1}し、計算を行い、適切な量のバッファ文字を出力できることはわかっていますが、毎回更新するにはどうすればよいですか。好ましい方法はありますか?

4

2 に答える 2

6

プロンプトを次のようにしたいとします。

left text----------------------------------------------------------right text
prompt$ 

right textこれは、サイズがわかっている場合は非常に簡単です。(たとえば、現在の日付と時刻かもしれません。) 適切な数のダッシュ (または、utf-8 端末の場合はよりきれいな\u2500) を出力しright text、その後に 、改行ではなくキャリッジ リターン ( \r、改行ではない) を出力します。 ) とダッシュを上書きする左側のテキスト。唯一のトリッキーなビットは「適切な数のダッシュ」ですが$(tput cols)、端末の幅を確認するために使用でき、幸いbashなことに command-expand PS1. たとえば、次のようになります。

PS1='\[$(printf "%*s" $(($(tput cols)-20)) "" | sed "s/ /-/g") \d \t\r\u@\h:\w \]\n\$ '

ここで、端末の幅から 20 を引いた値は、正確に 20 文字の幅 (最初のスペースを含む) に$(($(tput cols)-20))基づいています。\d \t

PS1は utf-8 エスケープ ( \uxxxx) を理解せず、コマンドに適切な置換を挿入すると、sed可能ではあるものの、厄介な埋め込み引用符の問題が発生します。ただし、printfutf-8 エスケープを理解するので、別の方法で一連のダッシュを生成する方が簡単です。

PS1='\[$(printf "\\u2500%.0s" $(seq 21 $(tput cols))) \d \t\r\u@\h:\w \]\n\$ '

これを行うさらに別の方法は、端末の自動ラップをオフにすることです。これはxterm、同じ制御コードを実装する端末エミュレーター (または Linux コンソール自体) を使用している場合に可能です。autowrap を無効にするには、 sequence を出力しますESC[?7l。オンに戻すには、 を使用しますESC[?7h。autowrap を無効にすると、出力が行末に到達すると、新しい行を開始する代わりに、最後の文字が次の文字で上書きされます。この手法では、ダッシュ シーケンスの正確な長さを計算する必要はありません。次のように、どのコンソールよりも長いダッシュの文字列が必要なだけです。

DASHES="$(printf '\u2500%0.s' {1..1000})"
PS1='\[\e[?7l\u@\h:\w $DASHES \e[19D \d \t\e[?7h\]\n\$ '

これは、\e[19D「カーソルを 19 文字後方に移動する」ためのターミナル エミュレータ コードです。$(tput cub 19)代わりに使用できたはずです。(autowrap のオンとオフを切り替えるパラメーターがあるかもしれませんが、tputそれが何であるかはわかりません。)

ビデオの例では、実際のコマンド ラインに右揃えの文字列を挿入しています。bash;でこれを行うきれいな方法はわかりません。ビデオのコンソールは、ほぼ確実にこの機能を使用zshしていRPROMPTます。bashもちろん、上記と同じ手法を使用して で右揃えのプロンプトを出力できますがreadline、それらについては何もわからないため、行を編集するために何かを行うとすぐに、右のプロンプトは消えてしまいます。

于 2014-01-26T20:37:41.250 に答える