0

I am using code to execute an executable file via python in Linux Terminal.

The code I use in python is

import subprocess


def executable_shell():
    # to run cosmo file     
    x=subprocess.run('cd .. && cd build &&  ./COSMO', shell=True, capture_output=True)
    print(x)

executable_shell()

Here COSMO is my executable file To run this python file I use command: $ python3 file.py

The code is working but the display file is without line space between them, like each new line is starting on the same line rather than jumping to a new line.

But if I run this executable in the normal way from the terminal

$ ./COSMO

I am getting the correct format.

Example output:

xxxxx xxxxx xx

Desired output:

xxxxx
xxxxx
xx
3
  • Use text=True in options, and then access x.stdout to get the stream of bytes in return. x is not the output, it is an object that encapsulate the process management. Commented Feb 16, 2021 at 8:28
  • This could be an end of line conversion problem. To make sure, you should redirect the output of the COSMO executable to a file, and examine the content of the file with an hexadecimal editor (or just dump the content in hexa with a tiny Python script). Commented Feb 16, 2021 at 8:28
  • Not sure what COSMO bin does but try add to your print statement print("{}\r".format(x)) . Keep in mind that subprocess.run() returns a CompletedProcess instance aka a process that has finished when capture_output is true stdout and stderr will be captured Commented Feb 16, 2021 at 8:30

1 Answer 1

1

The code you are running would print a human-readable representation of a CompletedProcess object which includes, but contains much more than, the actual output from your subprocess, on a single line.

Python 3.7.2 (default, Mar 25 2020, 10:15:53) 
[Clang 11.0.3 (clang-1103.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> x = subprocess.run(['printf', '%s\n', 'foo', 'bar', 'baz'], capture_output=True)
>>> print(x)
CompletedProcess(args=['printf', '%s\n', 'foo', 'bar', 'baz'], returncode=0, stdout=b'foo\nbar\nbaz\n', stderr=b'')

To actually print only the output, try

>>> print(x.stdout.decode())
foo
bar
baz

Better yet, have Python decode it for you.

import subprocess


def executable_shell():
    # to run cosmo file     
    x = subprocess.run(
        # Just the command, as a list of arguments, so we can avoid shell=True
        ['./COSMO'],
        # Specify which directory to run it in
        cwd='../build',
        # Throw an exception if the command fails (optional but recommended)
        check=True,
        # Have Python decode the output as text instead of raw bytes
        text=True,
        # Capture output, as before
        capture_output=True)
    return x.stdout

print(executable_shell())

Notice how I added text=True (and also refactored to use check=True and get rid of shell=True) and how the function now returns the result, and the caller prints it (or does something else with it, as the case may be). Generally, you want functions to return results rather than print them; this makes it easier to reuse them for other tasks.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.