How to show the result of shell instantly

I stumbled over the same issue recently. All output of subprocess only showed up once the command finished executing so thatI wrote this small fix for Windows for me:

import subprocess
import shlex
import os
from IPython.core.magic import register_line_magic

codepage_output = !chcp
print("Command output: >>" + codepage_output.s + "<<")
codepage_digits = "".join([d for d in codepage_output.s.split(":")[1] if d.isnumeric()])
print("Parsed Codepage: >>" + codepage_digits + "<<")

def run_windows_command(command, output_function=print):
    print(f"=== Executing command: {command}")
    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=os.environ.copy())
    while True:
        stdout_line = process.stdout.readline().decode(f"CP{codepage_digits}")
        if not stdout_line:
            break
        else:
            print(stdout_line.replace("\r\n", "\n")[:-1])  # Remove '\r\n' and '\n'
    print(f"\n=== Command has finished")

@register_line_magic
def cmd_unbuffered(line):
    line_with_resolved_vars = line.format(**globals(), **locals())
    return run_windows_command(line_with_resolved_vars)

Now you can write something like this in a cell:

%cmd_unbuffered PING 127.0.0.1 -n 1

I have only scratched on the surface of the documenation, I am sure that there is a more elegant way of doing in. Additionally, this does not check for Linux and assumes that everything works like under Windows, e.g. the command chcp.

3 Likes