-1

I call another script with subprocess.check_call and I do not want to see on my console prints from the other script. I tried: stdout=subprocess.DEVNULL and stderr=subprocess.DEVNULL, but I still see some output printed.

With one of my script worked with stderr and with one with stdout. Why is not working?

subprocess.check_call(cmd, timeout=timeout_sec, shell=True,  stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 

What can I found If I need stdout or stderr?

Nick ODell
  • 15,465
  • 3
  • 32
  • 66
Cezar
  • 3
  • 2
  • 1
    Is the subprocess maybe opening `/dev/tty` and printing to that? This [answer](https://stackoverflow.com/a/50072485/530160) suggests using `setsid()` to block this, which you can do using subprocess by passing `start_new_session=True` to `check_call()`. – Nick ODell Aug 23 '23 at 18:59
  • Not working, I tried start_new_session=True – Cezar Aug 24 '23 at 18:31

1 Answers1

0

Instead of using check_call, I use run, which offers more options.

import subprocess


def main():
    cmd = ["./doit.sh"]  # Can be anything
    timeout_sec = 10

    completed_process = subprocess.run(
        cmd,
        timeout=timeout_sec,
        shell=True,
        check=True,  # Behave like check_call
        text=True,  # Capture stdout, stderr as text, not bytes
        capture_output=True,  # Capture to internal .stdout, .stderr
    )

    # Do something with stdout and stderr
    print("STDOUT:")
    print(completed_process.stdout)
    print("STDERR:")
    print(completed_process.stderr)


if __name__ == "__main__":
    main()

Notes

  • The run function returns a CompletedProcess object, which includes stdout, stderr among other attributes
  • Normally, stdout and stderr are bytes, the text=True argument will change that so they are str instead
  • The capture_output=True argument will suppress printing of stdout and stderr and capture them into attributes of the CompletedProcess object.
Hai Vu
  • 37,849
  • 11
  • 66
  • 93