교육 목적으로 터미널에 연결된 실행 중인 bash 프로세스의 strace 출력을 보고 있습니다.
내 bash 프로세스의 PID는 2883입니다.
나는 들어간다
[OP@localhost ~]$ strace -e trace=openat,read,write,fork,vfork,clone,execve -p 2883 2> bash.strace
터미널을 입력하십시오. 그런 다음 bash 프로세스에 들어가서 다음 상호 작용을 수행합니다.
[OP@localhost ~]$ ls
출력을 보니 이해가 되네요
strace: Process 2883 attached
read(0, "l", 1) = 1
write(2, "l", 1) = 1
read(0, "s", 1) = 1
write(2, "s", 1) = 1
read(0, "\r", 1) = 1
write(2, "\n", 1) = 1
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fec6b1d8e50) = 3917
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=3917, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
write(1, "\33]0;OP@localhost:~\7", 23) = 23
write(2, "[OP@localhost ~]$ ", 22) = 22
...
마지막 두줄이 헷갈리네요. bash가 두 개의 쉘 프롬프트를 작성하려고 하는 것 같나요? 여기서 무슨 일이 일어나고 있는 걸까요?
답변1
이 <ESC>]0;
시퀀스( strace 로 표시 \33]0;
)는 터미널 창 제목을 설정하는 이스케이프 시퀀스입니다. BEL 문자( )로 끝나므로 \7
첫 번째 문자가 write
창 제목을 설정합니다. 두 번째는 실제 프롬프트를 인쇄합니다. 이스케이프 시퀀스를 제외하고는 동일하지 않습니다. 프롬프트에는 서라운드가 있지만 [..]
창 제목에는 없습니다.
write()
또한 stdout에 대한 첫 번째 쓰기(fd 1, 첫 번째 매개변수 )와 stderr에 대한 두 번째 쓰기 도 볼 수 있습니다 . Bash는 프롬프트를 stderr에 인쇄하므로 첫 번째 쓰기는 다른 곳에서 이루어집니다. 아마도 PROMPT_COMMAND
데비안의 Bash 기본 시작 스크립트에 있는 것과 같은 어딘가에 있을 것입니다. 그 안에는 다음과 같은 내용이 있습니다.
case "$TERM" in
xterm*|rxvt*)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
;;
*)
;;
esac
또는 PROMPT_COMMAND
실행 중인 경우 설정되며 해당 이스케이프 시퀀스를 지원해야 합니다.xterm
rxvt