우리 모두는 이 성가신 문제를 알고 있습니다.
$ printf "abc" > some-file
$ cat some-file
abc$
그보다 더 복잡하면 프롬프트를 엉망으로 만들고 $
현재 커서 위치를 버리고 보기 흉하게 보이는 경향이 있습니다. 몇 가지 해결책이 있습니다(예:여기), 그러나 또 다른 단점이 있습니다. SSH를 통해 느린 시스템에 로그인할 때 프롬프트가 나타나기 전에 입력을 시작할 수 있습니다. 일반적으로 입력은 버퍼링되어 가능한 한 빨리 표시됩니다. 그러나 연결된 솔루션의 경우 입력이 삭제됩니다.
내가 어떻게 할
- 항상 새 줄에서 프롬프트를 시작하세요. 마지막 명령의 출력이 새 줄로 끝나지 않는 경우그리고
- 이전 명령을 실행하는 동안 입력된 사용되지 않은 입력을 명령줄 버퍼에 유지하시겠습니까?
답변1
이 솔루션은 약간 결합문제 해결와작은 Perl 조각:
다음 코드는 .bashrc
두 개의 새로운 함수 inject
와 clear_newline
. 후자는 인쇄 프롬프트가 필요할 때마다 호출됩니다. 전자는 후자 내에서 호출됩니다(자세한 내용은 인라인 명령 참조).
# injects the arguments into the terminal, from the second link
function inject() {
perl -e 'ioctl(STDIN, 0x5412, $_) for split "", join " ", @ARGV' "$@"
}
# prints a newline if the cursor is not in position 1
clear_newline() {
local curpos # local variable to hold the cursor position
local input # local variable to hold entered input
stty -echo # disable echoing
inject '
' # inject a newline to terminate entered input, '\0' didn't work?
IFS='\n' read -s input # read entered input
echo -en '\033[6n'
# ask the terminal driver to print the current cursor position
IFS=';' read -d R -a curpos # read cursor position
stty echo # enable echoing
(( curpos[1] > 1 )) && echo -e '\033[7m%\033[0m'
# if cursor not in first column, print a % with inverted colours and a newline
stty -echo # disable echoing of input to terminal again
inject "${input}" # inject stored input
stty echo # enable echo
}
PROMPT_COMMAND='clear_newline' # run clear_newline for every prompt
두 번째 stty -echo/stty echo
쌍은 삽입된 입력을 숨기는 데 필요합니다. bash는 프롬프트가 완료되자마자 이를 인쇄합니다.