I am looking at the strace output of a running bash process connected to
a terminal, for educational purposes.
My bash process has PID 2883.
I type
[OP@localhost ~]$ strace -e trace=openat,read,write,fork,vfork,clone,execve -p 2883 2> bash.strace
Into a terminal. I then go into my bash process, and have the following
interaction:
[OP@localhost ~]$ ls
Looking at the output, I see
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
...
I am confused at the last two lines. It appears that bash is attempting
to write two shell prompts? What's going on here?
Best Answer
The
<ESC>]0;
sequence (shown as\33]0;
by strace) is the escape sequence to set the terminal window title. It's terminated with the BEL character (\7
), so the firstwrite
sets the window title. The second prints the actual prompt. Note that even apart from the escape sequence, they're not exactly the same. The prompt has a surrounding[..]
while the window title doesn't.We can also see that the first write goes to stdout (fd 1, the first argument to
write()
), and the second to stderr. Bash prints the prompt to stderr, so the first write comes from somewhere else. That somewhere is probablyPROMPT_COMMAND
, like the one in Debian's default startup scripts for Bash. There's something like this in there:It sets that
PROMPT_COMMAND
if runningxterm
orrxvt
, which should support that escape sequence.