줄 길이 계산을 중단하지 않고 Bash의 PS1에 명령을 포함시키는 방법은 무엇입니까? 종료 코드를 포함합니다. 1 $ Ctrl-를

Tonin 기본 프롬프트 에서 버그지적했습니다 . 최소 예 :

  1. PS1 설정 :

    PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " ")$ '

    이 시점에서 프롬프트는 다음과 같습니다.

    $ 
  2. 이제 다음을 실행하여 종료 코드 출력을 트리거하십시오.

    false

    이제 프롬프트는 줄의 시작 부분에 빨간색으로 종료 코드를 포함합니다.

    1 $ 
  3. Ctrl-를 누르십시오 r.
  4. “false”를 입력하십시오. 이제 프롬프트에는 검색 만 포함됩니다.

    (reverse-i-search)`false': false
  5. 를 누릅니다 Enter.

결과 터미널 히스토리에는 이제 다음이 포함됩니다.

1 $ch)`false': false

예상 출력 :

1 $ false

즉, 히스토리 검색 출력이 프롬프트와 혼합 되어 실행 된 실제 명령을 숨기는 것 같습니다 .

나는 이것을 사용PROMPT_COMMAND 하여이 문제를 해결하려고 시도했다 .

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " "
}
set_bash_prompt() {
    PS1='$(set_exit_code)$ ' # Double quotes give the same result
}
PROMPT_COMMAND=set_bash_prompt

이것은 작동하지 않는 것 같습니다-라인은 검색 및 실행 후와 정확히 동일하게 보입니다.

이 문제를 어떻게 해결할 수 있습니까?



답변

askubuntu.com 에서 답을 찾았습니다 . @qeirha는 bash에게 일련의 문자가 프롬프트 길이로 계산되어서는 안된다고 말해야하며을 묶어서 그렇게해야한다고 언급했습니다 \[ \]. 제공된 예제를 기반으로 한 가지 솔루션이 있습니다.

red=$(tput setaf 1)

reset=$(tput sgr0)

[ "$PS1" = "\\s-\\v\\\$ " ] && PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$red\] $exit_code \[$reset\] " ")$ '

답변

PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " ")$ '

(죄송합니다, 여기에 대한 설명은 없습니다. PS1을 올바르게 사용자 정의하는 방법? 또는 프롬프트 길이 계산 문제 및 \[..에 대한 다른 질문 참조하십시오 \].)


답변

@manatwork 답변을 확장하지만 코드를 PS1계산하여 다른 기능으로 분할 하면 다음과 같은 방법으로 프롬프트를 작성할 수 있습니다.

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf "\[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] "
}
set_bash_prompt() {
    PS1="$(set_exit_code)$ " # with double quotes!
}
PROMPT_COMMAND=set_bash_prompt

큰 따옴표는 설정 PS1printf기능에서 사용할 때 필수 입니다.