저는 Ubuntu 18.04를 실행 중이고 다음과 같이 bash 프롬프트를 설정하고 싶습니다.
user:~/Documents [14:22:07] 1 $
내 PS1은 다음과 같습니다
ALERT_COLOR="$(tput setaf 1)"
# Display unsuccessful exit codes
function exit_status {
last_status=$?
if [[ $last_status != 0 ]]; then
echo "$ALERT_COLOR[$last_status]"
fi
}
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)\[\033[00m\] \[\033[36m\][\t] \[$ALERT_COLOR\]$exit_status \[\033[0;37m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u:\w$(parse_git_branch)\$ '
fi
unset color_prompt force_color_prompt
종료 코드를 제외하고 모든 것이 잘 작동합니다. 종료 코드가 표시되지 않습니다. $?
PS1에서 이 작업을 수행하면 항상 표시됩니다.0
답변1
문제는 여기에 있습니다:
PS1='...\[$ALERT_COLOR\]$exit_status ...\$ '
^^
이는 매개변수 확장이므로 설정한 함수를 호출하지 않습니다. 예를 들어 $(exit_status)
, from 과 같은 명령 대체에서 함수를 호출해야 합니다 PROMPT_COMMAND
. 이렇게 하면 탈출에 주의하세요 \[ .. \]
. Bash가 이를 해석합니다.앞으로프롬프트의 다른 확장이므로 프롬프트 문자열에 하드코딩해야 합니다(프롬프트에서 확장된 변수나 기타 항목의 일부가 될 수 없음).
변수를 확장하지 않고 신속하게 탈출하는 것이 당신에게 거꾸로 보인다면, 나는 당신을 비난할 수 없습니다. 하지만이렇게 기록되어 있어요:
또한 다음 표에서는 프롬프트 변수에 나타날 수 있는 특수 문자에 대해 설명합니다
PS1
.PS4
[...] 문자열을 디코딩한 후, 매개변수 확장 및 명령 대체를 통해 확장,[...]
다음과 같이 작동해야 합니다.
normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color
set_exit_color() {
if [ "$?" != 0 ]; then
exit_color=$red_color
else
exit_color=$normal_color
fi
}
PROMPT_COMMAND=set_exit_color
PS1='\[$exit_color\][$?]\[$normal_color\] \w\$ '
종료 상태를 유지하려면 임시 변수가 필요하다고 생각했지만 분명히 프롬프트에서 확장된 값은 PROMPT_COMMAND
수정되지 않습니다 . $?
프롬프트 문자열 내부에서 명령 대체를 사용하여 함수를 호출하는 경우 명령 대체에 대한 종료 코드가 적용되므로 해결 방법이 필요합니다. 이 같은:
normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color
exit_color() {
exit_code=$?
if [ "$exit_code" != 0 ]; then
echo "$red_color"
else
echo "$normal_color"
fi
return "$exit_code"
}
PS1='\[$(exit_color)\][$?]\[$normal_color\] \w\$ '
명령 대체로 인한 하위 쉘 분기를 저장하기 위해 with 버전을 사용 PROMPT_COMMAND
하지만 실제로는 거의 효과가 없습니다.
답변2
나는 3줄의 프롬프트를 갖고 싶기 때문에 다음과 같이 합니다:
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 10:56:52
jackman@jackmanVM:~/tmp
+$ cat ~/.bash_prompt
# ... some other stuff ...
__bash_prompt() {
local last_status=$1
local cwd=$( sed "s,^$HOME,~," <<<"$PWD" )
local user_host_path="${debian_chroot:+($debian_chroot) }$(id -un)@$(hostname -s):$cwd"
# terminal title
echo -ne "\e]0;$user_host_path\a"
# separator and date
local char="۰"
printf "%s bash %s " "$(jot -s "" -b "$char" $(( $(tput cols) - 18 )) )" "$char$char"
date '+%T'
if ((last_status != 0)); then
local color_bold='\e[0;1m'
local color_reset='\e[0m'
printf "$color_bold[%d]$color_reset " $last_status
fi
# user@host, directory, git branch
printf "%s%s\n" "${user_host_path}$(git_current_branch " (%s)")"
}
# ref: https://stackoverflow.com/questions/1039713/different-bash-prompt-for-different-vi-editing-mode
# a single-line PS1 allows the show-mode-in-prompt inputrc setting to be useful
PROMPT_COMMAND='__bash_prompt $?'
PS1='\$ '
~/.bashrc에서 파일을 얻습니다.
종료 상태는 다음과 같이 표시됩니다
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:10
jackman@jackmanVM:~/tmp
+$ sh -c 'exit 42'
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:14
[42] jackman@jackmanVM:~/tmp
+$ false
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:16
[1] jackman@jackmanVM:~/tmp
+$ true
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:17
jackman@jackmanVM:~/tmp
+$
함수에서 가장 먼저 하는 일은 다른 명령을 실행하기 전에 마지막 종료 상태를 저장하는 것입니다.
나는 PROMPT_COMMAND를 사용하여 모든 멋진 것들을 출력하고 vi 모드를 사용하고 vi 모드 표시기를 보는 것을 좋아하기 때문에 간단한 PS1만 가지고 있습니다. 나는 또한 이것을 가지고 있습니다 :
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 10:57:21
jackman@jackmanVM:~/tmp
+$ cat ~/.inputrc
set editing-mode vi
set show-mode-in-prompt on
$if Bash
# not until bash 4.4, I believe
# escape sequences: https://stackoverflow.com/a/42107711/7552
#set vi-ins-mode-string "+\1\e[5 q\2"
#set vi-cmd-mode-string ":\1\e[1 q\2"
set vi-ins-mode-string +
set vi-cmd-mode-string :
$endif
나는 사용한다물고기로그인 셸로 사용하고 때로는 ksh에 사용하므로 프롬프트 구분 기호에 셸 이름을 넣어 입력 중인 내용을 추적할 수 있습니다.