Bash

Bash 嘗試編寫兩個 shell 提示?

  • September 15, 2019

出於教育目的,我正在查看連接到終端的正在執行的 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 正在嘗試編寫兩個 shell 提示?這裡發生了什麼?

*<ESC>*]0;序列(顯示為\33]0;strace)是設置終端視窗標題的轉義序列。它以 BEL 字元 ( \7) 結束,因此第一個write設置視窗標題。第二個列印實際提示。請注意,即使除了轉義序列之外,它們也不完全相同。提示有周圍[..],而視窗標題沒有。

我們還可以看到,第一次寫入到 stdout(fd 1,第一個參數到write()),第二次寫入到 stderr。Bash 將提示列印到 stderr,因此第一次寫入來自其他地方。這可能是某個地方PROMPT_COMMAND,就像 Debian 的 Bash 預設啟動腳本中的那個。裡面有這樣的東西:

case "$TERM" in
xterm*|rxvt*)
   PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
   ;;
*)
   ;;
esac

它設置PROMPT_COMMAND如果執行xtermor rxvt,它應該支持該轉義序列。

引用自:https://unix.stackexchange.com/questions/541909