I made a terminal by binding bash with QProcess:

// c++ in Qt4.8.7 on CentOS7
process_ptr->start("bash -i", QIODevice::ReadWrite | QIODevice::Append);
// With the "-i" option, interactive bash is able to display the *prompt*

Commands are entered through QCmdLine, fed to QProcess, and the output is printed to QPlainTextEdit

And I have merged the standard output channel with the standard error channel:


The problem is: the command prompt(set by PS1) in QPlainTextEdit, which is used to display stdout or stderr, is messy.

Specifically, the content printed in QPlainTextEdit is as follows:

^[]0;eng@hostname:~^G[eng@hostname 15:36:41 #17 ~]$

^[]0;eng@hostname:~^G[eng@hostname 16:05:12 #18 ~]$
echo $PS1
[\u@\H \t #\# \W]\$
^[]0;eng@hostname:~^G[eng@hostname 16:05:35 #19 ~]$

^[]0;eng@hostname:~^G[eng@hostname 16:05:36 #19 ~]$

And I have set PS1 as

PS1="[\u@\H \t #\# \W]\$ "

It looks like the second half of the command prompt [eng@hostname 15:36:41 #17 ~]$ is what I set up correctly via PS1.

Now I don't know how to get rid of the first half ^[]0;eng@hostname:~^G, where ^[ denotes the ASCII control character "ESC" and ^G denotes the ASCII control character "BEL"

I've researched the concept of tty for this issue: my practice of binding a fixed bash via QProcess bypasses line discipline and pty, in other words input and output content is written/read directly to the bash process without going through line discipline and pty(Here's the link, it might be useful: tty/pty)

At the moment I'm not sure which module I should look at to locate the root cause of the problem: standard output/error channel redirection, the underlying principles of bash, QPlainTextEdit in Qt, etc.

Thank you very much for your valuable thoughts or solutions!

  • Are you going to take care of that terminal for a longer time? I ask because Qt4 is actually in the process of being phased out (since 2018/19 of I remember correctly!), and thus I'm a bit surprised you're using it to develop something new! Commented Oct 26, 2023 at 9:03
  • @MarcusMüller Custom terminal do need to be used for a long time. The reason for using version 4.8.7 is that newly developed applications need to work with existing Qt applications (4.8.7): inter-process communication via QUdpSocket or QDBus*. I understand your surprise, but there are still a lot of people using Qt4 for development (it's very robust)~q(≧▽≦q)~
    – Qipa
    Commented Oct 26, 2023 at 9:31
  • I get that, though UDP and dbus bindings do exist for Qt5 and Qt6. Commented Oct 26, 2023 at 9:33
  • I suspect your problem has to do with terminal control ANSI escape sequences, and we're only seeing the printable characters. Did you have a look at a hexdump of the data to see whether it might contain unprintable characters? Commented Oct 26, 2023 at 9:38
  • @MarcusMüller Extremely grateful! I'll study the ANSI escape sequences and debug it right away. So much to learn! o(≧口≦)o
    – Qipa
    Commented Oct 26, 2023 at 9:49

1 Answer 1


There is probably something in your .profile (or .bash_profile - or even, wrongly, .bashrc) that modifies your PS1. For example, on my system, bash -ix -c true 2>&1 | grep PS1= | cat -v reveals these:

+ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
++ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
+ PS1='\[^[[1m^[[32m\]\u@\h\[^[[39;49m\]:\[^[[34m\]\w\[^[(B^[[m\]\$ '
+ PS1='\[\033]0;\u@\h: \w\007\]\[^[[1m^[[32m\]\u@\h\[^[[39;49m\]:\[^[[34m\]\w\[^[(B^[[m\]\$ '

A likely underlying cause is that you have TERM set in the environment from the shell which executed the Qt program. Well-behaved startup scripts will use tput or similar to find the correct escape sequences, so exporting TERM=dumb to your shell process should give a plain prompt. We can demo this using TERM=dumb bash -ix -c true 2>&1 | grep PS1= | cat -v:

+ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
++ PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
+ PS1='\[\]\u@\h\[\]:\[\]\w\[\]\$ '

If I remember correctly, the ^[]0;^G sequence is an xterm control code to set the window title.

  • Appreciate it very much! o(^@^)o Following your tips, the problem has been solved: Method: PROMPT_COMMAND="" (PROMPT_COMMAND). Specifically, I have observed the PROMPT_COMMAND related scripts/functions, which have case statements to determine if the TERM variable is xterm or not. One oddity is that the PROMPT_COMMAND related content still prints even if I set TERM to dumb; this can only be resolved by manually clearing the PROMPT_COMMAND variable. Thanks again!
    – Qipa
    Commented Nov 14, 2023 at 11:46
  • Some programs think they know best, and completely ignore TERM. It looks like you have found one; I recommend submitting a bug report to get it fixed (but in the meantime, simply not using it is a reasonable short-term workaround). Commented Nov 17, 2023 at 7:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .