PS1
私の中に私のもの~/.bash_profile
:
export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]`__git_ps1`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
(申し訳ありませんが、私のカラーコードにエイリアスはありません。このヒントはオンラインエディタを使用して作成しました。)
しかし、切り替えると、現在表示されているブランチは常に間違っています。
なぜこれが起こるのかわかりません。コマンドのみを実行すると正しい値が得られます。
$ echo `__git_ps1`
(dev)
.bash_profileを取得すると、新しい値が表示されます(ただし、次回の切り替え時にエラーが発生します)。私は何が間違っていましたか?
答え1
export PS1="…`__git_ps1`…"
`__git_ps1`
このコマンドは内部二重引用符を使用してコマンドを実行し__git_ps1
、その出力(およびその他の周辺テキスト)を変数に割り当てますPS1
。したがって、プロンプトには、.bash_profile
実行時に決定された分岐が表示されます。
__git_ps1
Bashがプロンプトを表示するたびにこのタスクを実行する必要があります。 (実際にgit情報が変わるまで再度実行する必要はありませんが、検出するのは難しいです。)これを行うには2つの方法があります。
`__git_ps1`
変数にリテラルテキストを含めますPS1
。以下を使用して、プロンプト文字列のシェル拡張を実行するように bash が構成されていることを確認します。promptvars
オプションオンはデフォルトで設定されていますが、を使用してオフにすることができますshopt -u promptvars
。PS1='\n\[…\]$(__git_ps1)\[…\]\$ '
次のコマンドを実行してプロンプトの内容を更新します。
PROMPT_COMMAND
変えるupdate_PS1 () { PS1="\\n\\[…\\]$(__git_ps1)\[…\]\\$ " } shopt -u promptvars PROMPT_COMMAND=update_PS1
しかし、プロンプトはグローバル設定ではなくシェル構成なので、~/.bashrc
代わりにに設定する必要があります~/.bash_profile
。
答え2
ただ引用の問題にすぎません。バックティックを使用する必要がある場合は、または`__git_ps1`
に変更してください。\$(__git_ps1)
\`__git_ps1\`
確信を得るには、PS1を次のように変更します(以前の設定に完全に戻すには、新しいシェルインスタンスを開きます)。
$ PS1="$(date) >"
Thu Nov 26 20:02:34 EST 2015 >_
唯一の問題はそうなることだ。いいえアップデート(数秒待ってからEnterキーを押します)。
しかし、これは次のとおりです。
$ PS1="\$(date) >"
Thu Nov 26 20:06:20 EST 2015
Thu Nov 26 20:06:25 EST 2015
それはすべてです。書くexit
。 (ヒントの更新)もう一度仕事を始めてください。
答え3
http://mediadoneright.com/content/ultimate-git-ps1-bash-prompt
下部に設定はありません。
PS1="\n... `__git_ps1 ... エクスポート
この嫌な創造物に設定してください:
export PS1=$IBlack$Time12h$Color_Off'$(git branch &>/dev/null;\
if [ $? -eq 0 ]; then \
echo "$(echo `git status` | grep "nothing to commit" > /dev/null 2>&1; \
if [ "$?" -eq "0" ]; then \
# @4 - Clean repository - nothing to commit
echo "'$Green'"$(__git_ps1 " (%s)"); \
else \
# @5 - Changes to working tree
echo "'$IRed'"$(__git_ps1 " {%s}"); \
fi) '$BYellow$PathShort$Color_Off'\$ "; \
else \
# @2 - Prompt when not in GIT repo
echo " '$Yellow$PathShort$Color_Off'\$ "; \
fi)'
関連ビットは "$(__git_ps1"(%s)" または "$(__git_ps1"{%s}") です。
答え4
既存の回答が根本原因を正確かつ明確に伝えることができないようです。解決策につながるかもしれませんが、聴衆に学ぶべき教訓を教えるかどうかはわかりません。この回答は、主に聴衆の理解を助けるという観点からのものです。
迅速な回答
もともと返事を書いた後、このようなアプローチが考えられ、以下に詳細な返信を残す予定ですが、ここに速い答えがあります。
入力中にエスケープが使用されなかったため、値PS1
は代替バージョンとして保存されます。次のように確認できます。
オリジナル:
chadb@Chad-2in1 ~/code/videospeed-refactoring (master) 21:12:45
$ export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]`__git_ps1`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
chadb@Chad-2in1 ~/code/videospeed-refactoring (master) 21:13:03
$ env |grep PS1
PS1=\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\] (master)\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\$
脱出する
chadb@Chad-2in1 ~/code/videospeed-refactoring (master) 21:19:42
$ export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]\`__git_ps1\`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
chadb@Chad-2in1 ~/code/videospeed-refactoring (master) 21:20:02
$ env |grep PS1
PS1=\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]`__git_ps1`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\$
見てわかるように、__git_ps1
2番目のバージョンではこれが維持され、最初のバージョンでは入力時に__get_ps1の値が表示されます。
私の元の答えを続けます。
説明する
問題は、シェルがコマンドを実行するときに挿入する前に置換を実行するため、元のコマンドの代わりに置き換えられた値が挿入されることです。
この問題を解決するには、\
置換を防ぐために保存する前にエスケープ文字を使用してください。これにより、コマンドのエスケープされていない実行可能バージョンがメモリに保存され、bashが入力された各コマンドでバージョンを再評価します。
コマンドをエスケープ解除すると、メモリに保存される前にコマンドが実行および置き換えられ、その結果、コマンドが最初に~/.bash_profile
実行/インポートされたときにのみコマンドが表示されます。
解決策
オリジナルコマンド
export export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]`__git_ps1`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
$ PS1の元の保存値
文字列リテラル「(master)」を含みます。
\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\] (master) \[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$
重要:混乱を避けるために、この保存された値は
__git_ps1
固定コマンド
export export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]\`__git_ps1\`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
$PS1の固定保存価値
今回はコマンドは変更されていないため、次回実行時に置き換えられます。
"\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]`__git_ps1`\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
バックティックは関係ありません - 証明
他の回答で述べたように、$()を使用してバックティックを提供できますが、これはこの問題の根本的な原因とは関係ありません。これらの問題を混同しないでください。
老いたこと[問題ない]
`__git_ps1`
新しいもの[問題なし]
$(__git_ps1)
元のコマンドにはバックティックがなく、エスケープされません。 [問題ではなく同じ問題になります。]
export export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]$(__git_ps1)\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
バックティックなしでエスケープされるネイティブコマンド[エスケープを使用して同じ方法で修正されました]
export export PS1="\\n\[\033[38;5;246m\]\u@\[\033[38;5;245m\]\h\[\033[38;5;15m\] \[\033[38;5;28m\]\w\[\033[38;5;15m\]\[\033[38;5;2m\]\$(__git_ps1)\[\033[38;5;15m\] \[\033[38;5;90m\]\t\[\033[38;5;15m\] \[\033[38;5;232m\]\[\033[38;5;15m\] \n\[\033[38;5;0m\]\\$ "
簡略化された証明
sub_demo
これを簡単にするために、中間状態を表示するためにファイルを記憶媒体として使用して現在の作業ディレクトリをコンソールにエコーすることを除いて、bashに似た操作を実行するカスタムシェルコマンドを作成して多くの変数を削除します。
エスケープされていない $PWD [問題]
[07:18 PM] ~/code $ echo $PWD
/c/Users/chadb/code
[07:36 PM] ~/code $ echo $PWD > sub_demo
[07:36 PM] ~/code $ cat sub_demo
/c/Users/chadb/code
代替値が$PWD
ファイルに保存され、ディレクトリの検索に使用されたコマンドに関する情報が破損しています。これから sub_demo の内容を読み込むと、常に同じレンダリング値が生成されます。/c/Users/chadb/code
愚かなことですが、説明のために複数の場所からファイルの内容を読み取って、実際に保存された情報が変更されないことをお見せしましょう。
[08:01 PM] ~/code $ cat ~/code/sub_demo
/c/Users/chadb/code
[08:01 PM] ~ $ cat ~/code/sub_demo
/c/Users/chadb/code
[08:01 PM] ~/code/sub_demo_folder $ cat ~/code/sub_demo
/c/Users/chadb/code
この値はフォルダに関係なく変更されません。内容を変更するまで~/code/sub_demo
これから内容を確認してください。/c/Users/chadb/code
$PWD脱出[解決策]
次に、$
エスケープ文字を渡すかどうかを検討します\$
。
[08:06 PM] ~/code $ echo \$PWD > sub_demo
[08:06 PM] ~/code $ cat sub_demo
$PWD
ご覧のとおり、値はコマンドとして保存されます。作業ディレクトリを見つけるために必要なのと同じコマンドです。何が役に立ちますか?さて、bashは$ PS1に格納されている値を実行します。ファイルの内容を実行可能ファイルに変換するために、最初にエコーを追加してこれをシミュレートしましょう。
完全性と比較のために、エスケープされていないバージョンとエスケープされたバージョンを紹介します。
[脱出しない]
[08:06 PM] ~/code $ echo "echo $PWD" > sub_demo
[08:11 PM] ~/code $ cat sub_demo
echo /c/Users/chadb/code
[脱出する]
[08:11 PM] ~/code $ echo "echo \$PWD" > sub_demo
[08:13 PM] ~/code $ cat sub_demo
echo $PWD
まだそれほど興味深いものではありませんが、出力を実行すると真の魔法が起こります。
最終簡略化された証明
エスケープされない - 動作しません
[08:15 PM] ~/code $ echo "echo $PWD" > sub_demo
[08:15 PM] ~/code $ cat sub_demo
echo /c/Users/chadb/code
[08:15 PM] ~/code $ cd sub_demo_folder/
[08:15 PM] ~/code/sub_demo_folder $ cat ~/code/sub_demo | bash -
/c/Users/chadb/code
[08:15 PM] ~/code/sub_demo_folder $ cd ~
[08:15 PM] ~ $ cat ~/code/sub_demo | bash -
/c/Users/chadb/code
[08:15 PM] ~ $ cd code
[08:15 PM] ~/code $ cat ~/code/sub_demo | bash -
/c/Users/chadb/code
観測された出力値は次のとおりです。いつも /c/Users/chadb/code
脱出 - 操作
[08:15 PM] ~/code $ echo "echo \$PWD" > sub_demo
[08:15 PM] ~/code $ cat sub_demo
echo $PWD
[08:16 PM] ~/code $ cd sub_demo_folder/
[08:19 PM] ~/code/sub_demo_folder $ cat ~/code/sub_demo | bash -
/c/Users/chadb/code/sub_demo_folder
[08:19 PM] ~/code/sub_demo_folder $ cd ~
[08:19 PM] ~ $ cat ~/code/sub_demo | bash -
/c/Users/chadb
[08:19 PM] ~ $ cd code/
[08:19 PM] ~/code $ cat ~/code/sub_demo | bash -
/c/Users/chadb/code
次に、コマンドが実行されるたびに正しいことを確認してください。現在の必要に応じてディレクトリ。