0

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:

process_ptr->setProcessChannelMode(QProcess::MergedChannels);

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 ~]$
ls

Desktop
Documents
Downloads
Music
Pictures
Public
Templates
Videos
^[]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!

9
  • 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)~ 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 Commented Oct 26, 2023 at 9:49

1 Answer 1

0

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.

2
  • 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! 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.