1

In my file 'wrapper.py' I call a subprocess and print its output to stdout at realtime . This works just fine if I call the python script from the console. However, when calling it from a jupyter notebook the code hangs at the line proc.stdout.readline(). All previous print statements work fine..

proc = subprocess.Popen(["calc", "input.txt"], cwd=__dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
    out = proc.stdout.readline().decode("utf-8")
    err = proc.stderr.readline().decode("utf-8")
    if out == '' and err == '' and proc.poll() is not None:
        break
    if out:
        print("::::%s"%(out), end='')
    if err:
        print("::::%s"%(err), end='', file=sys.stderr)
rc = proc.poll()
print("---> returns %s"%(rc))

Does anyone have an idea on how to fix this?

user2224350
  • 2,262
  • 5
  • 28
  • 54

1 Answers1

1

I use this custom function to execute a command in Notebooks.

import subprocess

def run_cmd(cmd: str, stderr=subprocess.STDOUT) -> None:
    """Run a command in terminal

    Args:
        cmd (str): command to run in terminal
        stderr (subprocess, optional): Where the error has to go. Defaults to subprocess.STDOUT.

    Raises:
        e: Excetion of the CalledProcessError
    """
    out = None
    try:
        out = subprocess.check_output(
            [cmd],
            shell=True,
            stderr=stderr,
            universal_newlines=True,
        )
    except subprocess.CalledProcessError as e:
        print(f'ERROR {e.returncode}: {cmd}\n\t{e.output}',
              flush=True, file=sys.stderr)
        raise e
    print(out)

Usecase:

run_cmd("pip install emoji")
Dharman
  • 30,962
  • 25
  • 85
  • 135
Harish Vutukuri
  • 1,092
  • 6
  • 14
  • But will this print realtime output (say if the command takes a long time to run)? My question has already been answered in a different post as pointed out by @yorodm – user2224350 Nov 26 '20 at 22:14