console output from guest (qemu VM) does no carriage return on host console when called with python subprocess.Popen

174 views Asked by At

I installed a virtual machine (guest) via qemu (qemu-system-x86_64) on a linux box (host). The virtual machine is also linux. On guest I have the following remote_bash_script.sh:

remote_bash_script.sh:

for (( count=1; count<=10; ++count )); do
  echo 'test message'
  sleep 1
done
exit 1

This script can be called via call_remote_bash_script.py from the host:

call_remote_bash_script.py:

import subprocess

my_command = "ssh -t user_name@ip_address \'./remote_bash_script.sh\'"
my_process = subprocess.Popen(my_command, shell = True, stdout=subprocess.PIPE, universal_newlines=True)

while True:
    my_line = my_process.stdout.readline()
    time.sleep(2)
    if not my_line:
        break
    print(my_line.strip())

The output is:

test message
            test message
                        test message
                                    test message
                                                test message
                                                            Connection to ip_address closed.
test message
test message
test message
test message
test message

If I run ssh -t user_name@ip_address "./remote_bash_script" off the command line, I get

test message
test message
test message
test message
test message
test message
test message
test message
test message
test message
Connection to ip_address closed.
user_name_host@host_name:~$

Question: why do I not get a carriage return while the connection is open? How can this be fixed?

I need output line by line since the process is long running.

The problem may be related with qemu settings, terminal settings or the way I am using Popen. I can provide more details on my linux and python setup if required.

I did fiddle with alternative subprocess methods as well as Popen arguments.

1

There are 1 answers

1
Disco12 On

The result of stdout.readline() includes a trailing newline and no carriage return, because that's the standard in Linux.

Now print seems to look at the string and says: If it is has any kind of newline or carriage return we send it to stdout as is. Otherwise I add a line ending matching the current's OS architecture.

You can fix it by stripping CR and NL from the received string. Then it should work.

my_line = my_process.stdout.readline().strip("\n\r")

Hope it helps