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 정보가 바뀔 때까지 다시 실행할 필요는 없지만 감지하기 어렵습니다.) 이를 수행하는 방법에는 두 가지가 있습니다.
`__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
두 번째 버전에서는 이것이 유지되는 반면, 첫 번째 버전에서는 입력 시 __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
이제 명령이 실행될 때마다 올바른지 관찰하십시오.현재의필요에 따라 디렉토리.