Bash $ PROMPT_COMMANDはスクロール履歴の表示をめちゃくちゃにします。

Bash $ PROMPT_COMMANDはスクロール履歴の表示をめちゃくちゃにします。

PROMPT_COMMANDGitリポジトリに現在のブランチを表示するように設定されています。

私の.bashrcの関連部分は次のとおりです。

export PS1=" \[\033[34m\]\$\[\033[0m\] "
export PROMPT_COMMAND="$HOME/bin/myprompt"

~/bin/myprompt は次のようになります。

#!/usr/bin/env ruby
green = "\033[32m"
bold = "\033[1m"
underline = "\033[4m"
reset = "\033[0m"

home_regex = Regexp.new "^#{ENV["HOME"]}"
Dir.chdir ENV["PWD"]

out = 
  underline + bold + green +
  `pwd`.gsub(home_regex, "~").chomp +
  reset

if `git log 2>&1 | grep ^fatal`.chomp == ""
  out += "#{underline}#{green} (#{`git branch | grep ^\* | sed s/^..//g`.chomp})#{reset}"
end

print out

ほとんどの場合うまく機能しますが、唯一の問題は、矢印キーを使用してコマンド履歴をスクロールするときに、コマンドが私のプロンプトを上書きすることです。次のセッションを想定します。

~ $ pwd
/Users/Adrian
~ $ cd sibilant
~/sibilant (master) $ pwd
/Users/Adrian/sibilant
~/sibilant (master) $

次に上矢印を押してコマンド履歴をスクロールします。各行には、矢印を一度押した結果が表示されます。

~/sibilant (master) $ pwd
~/sibilant (master) $ cd sibilant
~/spwd

ご覧のとおり、最後に矢印を押したときにプロンプ​​トにコマンドが記録されました。

この問題を経験したか、解決策を知っている人はいますか?

答え1

入れないで、PROMPT_COMMAND次のように入れてくださいPS1

PS1='$($HOME/bin/myprompt) \[\033[34m\]\$\[\033[0m\] '

ある場合、PS1bashは履歴をスクロールすると正しく再描画できるように印刷された文字数を計算します。これがbashに\[特殊\]文字がある理由です。この文字は埋め込み文字を印刷できないことをbashに伝え、必要に応じてプロンプトを再描画する方法をbashが理解するのに役立ちます。

コマンドの置き換えは一重引用符内にあります。これにより、割り当て中の拡張が防止されます。コマンド置換が二重引用符で囲まれているか引用符で囲まれていない場合、出力は割り当て時に一度キャプチャされ、myprompt静的に保持されます。時間の経過とともに変化する変数値をサポートするために、シェルはプロンプトを表示するPS1たびに値を拡張します。これは、割り当て時に参照によって拡張を防ぐ必要があることを意味します。これはまた速度に注意する必要があることを意味します。コマンドの置換を完了するのに1秒かかり、プロンプトが表示されるのに1秒かかります。

答え2

PROMPT_COMMANDには、bashが新しいプロンプトを印刷する前(つまりPS1が評価される前)に実行されるコマンドを含めることができます。

git 1.8.1では、PROMPT_COMMANDを使用してこれを効率的に実行するコードがリリースされました。バラよりPROMPT_COMMANDでgit-prompt.shを使用する。このコードは古いバージョンのgitで動作します。 contrib/completion/git-prompt.sh ファイルを .bashrc からインポートできる場所にコピーします。

乾杯

サイモン

関連情報