Bash 尝试编写两个 shell 提示符?

Bash 尝试编写两个 shell 提示符?

我正在查看连接到终端的正在运行的 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 提示符?这里发生了什么?

答案1

<ESC>]0;序列(由 strace 显示\33]0;)是设置终端窗口标题的转义序列。它以 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_COMMANDif runningxtermrxvt,它应该支持该转义序列。

相关内容