Bash: PS1의 조건부 개행 문자가 자동으로 중단됩니다.

Bash: PS1의 조건부 개행 문자가 자동으로 중단됩니다.

저는 Bash를 사용하고 있으며 PS1은 두 줄에 걸쳐 있습니다.

╭-ivan·dotfiles (master)
╰ဝ █

때로는 출력에 줄바꿈 문자가 없고 프롬프트가 잘못 정렬되는 명령을 실행합니다.

╭-ivan·dotfiles (master)
╰ဝ curl localhost:3002/is_alive
{"web_server_status":"success","db_status":"success"}╭-ivan·dotfiles (master)
╰ဝ █

커서가 첫 번째 열을 넘어서는 경우 프롬프트 앞에 조건부로 개행을 추가하는 솔루션을 마침내 찾았습니다.

build_prompt() {
  export PS1="\$(ps1_head)...
}

ps1_head() {
  if (( $(cursor_col) > 1 )); then
    printf '\n╭-'
  else
    printf '╭-'
  fi
}

cursor_col() {
  local _row col
  IFS=';' read -s -dR -p $'\033[6n' _row col
  echo "${col}"
}

이로써 원래의 문제가 해결되었습니다.

╭-ivan·dotfiles (master)
╰ဝ curl localhost:3002/is_alive
{"web_server_status":"success","db_status":"success"}
╭-ivan·dotfiles (master)
╰ဝ █

그러나 새로운 것을 소개합니다. 현재 명령이 완료되기 전에 다음 명령을 입력할 수 있도록 자동 완성 기능을 사용합니다. 조건부 래핑으로 인해 이 동작이 중단되는 것 같습니다.

조건부 래핑 논리가 없는 예:

╭-ivan·dotfiles (master)
╰ဝ git status
On branch master
Your branch is up-to-date with 'origin/master'.

lnothing to commit, working tree clean
s╭-ivan·dotfiles (master)
╰ဝ ls
myfile.txt

첫 번째 명령의 출력이 인쇄를 완료하기 전에 ( )를 입력했고 l, 첫 번째 명령이 완료된 후 프롬프트가 인쇄되기 전에 이를 입력했습니다. typeahead는 두 문자( )를 다음 명령으로 우아하게 가져옵니다.lnothing to commitsls

이제 내 프롬프트에서 조건부 래핑 논리를 사용하는 동일한 예가 있습니다.

╭-ivan·dotfiles (master)
╰ဝ git status
On branch master
Your branch is up-to-date with 'origin/master'.

lnothing to commit, working tree clean
s╭-ivan·dotfiles (master)
╰ဝ s
bash: s: command not found

이번에는 typeahead가 어떻게 s두 번째 명령을 우아하게 가져오지만 뒤에 남겨지는지 확인하세요 l.

이를 좀 더 우아하게 처리할 수 있는 방법이 있습니까? 아니면 결국 zsh로 전환해야 합니까?

답변1

이와 같은 동적 프롬프트 텍스트가 있는데 자동 완성에는 문제가 없습니다. 하지만 설정 메서드 호출 PS1에 프로세스 교체를 직접 포함하지 않았습니다 . PROMPT_COMMAND적절한 동적 텍스트를 생성하고 이를 변수에 저장한 다음 PS1.

그럼 이런 걸 시도해 보세요...

export ps1_head_text

build_prompt() {
  export PS1="\${ps1_head_text}..."
}

ps1_head() {
  if (( $(cursor_col) > 1 )); then
    ps1_head_text=$'\n'╭-
  else
    ps1_head_text=╭-
  fi
}

export PROMPT_COMMAND=ps1_head

나는 프로세스 대체에 문제가 있었기 때문에 결국 이 작업을 수행하게 되었습니다. (비록 이것이 미리 입력된 것인지 아니면 다른 것인지는 기억나지 않지만).

편집하다:지금 생각해보면 타이밍 문제가 있을 수 있습니다. PROMPT_COMMAND커서 위치를 올바르게 읽을 수 없는 시간에 if가 호출되고 있습니다. 이런 일이 발생하면 "zsh 사용"을 선택할 수 있습니다. 하지만 한번 시도해 보세요.


고쳐 쓰다:에 따르면dave_thompson_085의 댓글이스케이프 시퀀스(커서 위치를 인쇄하는 데 사용됨) 방출에 대한 응답을 읽으면 자동 완성 기능과 충돌할 수 있습니다.

자동 완성 텍스트가 입력된 동일한 셸에서 읽기가 발생하므로 이는 의미가 있습니다. 그렇다면 동일한 쉘에서 실행되지 않으면 어떻게 될까요? 괄호를 사용하여 하위 쉘에 넣는 것이 도움이 될까요? 터미널에서 응답을 리디렉션(예: 파일이나 파이프 등)하여 거기에서 읽는 것은 어떻습니까?

이 문제를 해결할 방법이 있을 것 같아서 벽에 몇 가지 물건을 던져 무엇이 붙는지 확인했습니다.

관련 정보