사용자 정의 bash 클라이언트 기록이 겹칩니다.

사용자 정의 bash 클라이언트 기록이 겹칩니다.

SSH를 통해 zimbra 서버에서 다양한 작업을 수행하기 위한 클라이언트를 작성 중인데 약간의 문제가 발생했습니다. 코드는 다음과 같습니다.

#!/bin/bash
set -e
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
export HISTCONTROL=ignoreboth

# History management
if [ -f $HOME/.zmcli_history ]; then
  history -r $HOME/.zmcli_history
else
  touch $HOME/.zmcli_history
  history -r $HOME/.zmcli_history
fi
trap "history -a $HOME/.zmcli_history && echo -e '\nExiting now.\n'" exit

# Styling
yellow='[33m'
bold='[1m'
off='[0m'

echo

# Client
while :; do
  read -ep "$bold${yellow}zimbra_cli[${off}server_domain$bold${yellow}]> $off" comm
  history -s "$comm"
done

참고: 이 스크립트를 실행하면 홈 디렉터리에 기록 파일(.zmcli_history)이 생성됩니다.

모든 것이 의도한 대로 작동하고 기록이 모두 있지만 기록을 계속 스크롤할 때 일부(보통 긴) 이전 명령의 일부가 남아 있는 경우가 많습니다. 명령의 해당 부분은 화면을 지우고 정상으로 재설정하는 CTRL+L을 누르지 않는 한 나머지 세션에 대한 프롬프트의 일부로 작동합니다. 나는 bash 터미널에서 이 문제를 겪는 사람들에게 도움이 되는 많은 게시물을 읽었습니다. 그들의 문제는 PS1의 형식이 부적절하고 bash가 프롬프트 문자열의 길이에 대해 혼란스러워했다는 것입니다. 아마도 비슷한 내용일 수 있지만 read 명령은 echo can(\e)과 같은 이스케이프 문자를 사용할 수 없기 때문에 해당 솔루션은 작동하지 않습니다.

리터럴 이스케이프(vim 삽입 모드에서 CTRL+V ESCAPE)를 사용하여 색상 시퀀스를 이스케이프하는 방법을 찾았습니다. 따라서 색상은 작동하지만 이 역사 문제에 봉착했습니다.

내가 시도한 것들:

  • 명령 대체 :: echo -e가 인쇄할 수 있는 방식으로 색상 코드를 작성하고 이스케이프한 다음 읽기 명령 $(echo -e '\e[33m')에 에코합니다. 여전히 색상이 표시되지만 기록 문제에는 도움이 되지 않았습니다.
  • 색상 코드 주위에 이스케이프된 [ 및 ] 추가
  • 읽기 명령 앞에 오는 별도의 echo 명령에 전체 프롬프트를 색상 코드로 넣습니다. 단점은 읽기 명령(다른 에코에서)이 끝날 때까지 서식 지정을 해제할 수 없다는 것입니다. 즉, 전체 프롬프트와 명령이 굵게 표시되고 색상이 지정됩니다. 또한 지금 Ctrl+L을 누르면 프롬프트도 지워지고 커서만 남게 됩니다.

마지막으로 이력을 버릴 수 없기 때문에 색상을 떨어뜨려 보았습니다. 그러나 그러면 명령과 출력을 빠르게 구별하는 것이 불가능해집니다.

스크립트를 시작하고 10-15개의 긴(횡설수설) 명령을 입력하여 문제를 재현할 수 있습니다. 그런 다음 기록을 위아래로 스크롤하면 내가 말하는 내용을 볼 수 있습니다.

이 작업을 수행하는 방법을 아는 사람이 있나요?

답변1

귀하의 스크립트,그대로, 문제를 재현할 수 없었습니다. 색상을 활성화한 후에야 그러한 readline이 혼란스러워지기 시작했습니다. 기록을 위해 저는 이러한 기능을 다음과 같이 활성화했습니다.

# Styling
yellow=$'\e[33m'
bold=$'\e[1m'
off=$'\e[0m'

그리고 그것은 사실 \[이고 \]도움이 되지 않습니다.그들은 경우에 따라서는PS1.

그런데 내가 발견한 건이 답변. 그것은 읽습니다

내가 열어서 info readline발견한 것:

[...] 응용 프로그램은 특수 마커 및 (에 선언된
) 문자 시퀀스를 괄호로 묶어 표시할 때 물리적 화면 공간을 차지하지 않는 문자가 프롬프트에 포함되어 있음을 나타낼 수 있습니다 . 이는 프롬프트에 터미널별 이스케이프 시퀀스를 포함하는 데 사용될 수 있습니다.RL_PROMPT_START_IGNORERL_PROMPT_END_IGNOREreadline.h

내가 검색 RL_PROMPT_START_IGNORE하고 RL_PROMPT_END_IGNORE정의한 텍스트 readline.h는 다음과 같습니다.

/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE  '\001'
#define RL_PROMPT_END_IGNORE    '\002'

이로 인해 나는 다음과 같은 결과를 얻었습니다.

# Styling
yellow=$'\1\e[33m\2'
bold=$'\1\e[1m\2'
off=$'\1\e[0m\2'

완벽하게 작동합니다.

관련 정보