Search code examples
pythonsubprocesspopen

How to clear the STDOUT of 'cmd.exe' with subprocess popen?


Problem

The code below is a simulation of a real terminal, in this case, a CMD terminal. The problem is that the "cls" don't clear the STDOUT of CMD. So, the string STDOUT start to stay so much extensive.

Example of problem

Microsoft Windows [versÆo 10.0.19042.746] (c) 2020 Microsoft Corporation. Todos os direitos reservados.

C:\Users\Lsy\PycharmProjects\Others>chdir

C:\Users\Lsy\PycharmProjects\Others

C:\Users\Lsy\PycharmProjects\Others>echo test

test

C:\Users\Lsy\PycharmProjects\Others>cls

Type:

Question

How to clear the STDOUT?

Script

import subprocess

f = open('output.txt', 'w')
proc = subprocess.Popen('cmd.exe', stderr=subprocess.STDOUT, stdin=subprocess.PIPE, stdout=f, shell=True)

while True:
    command = input('Type:')
    command = command.encode('utf-8') + b'\n'

    proc.stdin.write(command)
    proc.stdin.flush()
    with open('output.txt', 'r') as ff:
        print(ff.read())
        ff.close()

Solution

  • This is not how I recommend using sub processes - but I'm assuming you have some reason for doing things this way...

    Given:

    1. You've directed the CMD sub process to STDOUT to a file called "output.txt".
    2. The CLS character is captured in the output.txt.
    3. Your terminal then displaying the contents of the "output.txt" file (which is not ever cleared) and leaves a mess.

    Therefore: If you want to "clear" your sub process terminal, then you will have to flush your "output.txt" file. You can trivially do this by processing on the "command" variable before encoding and sending it to the sub process.
    e.g:

    import subprocess
    import os
    f = open('output.txt', 'w')
    proc = subprocess.Popen('cmd.exe', stderr=subprocess.STDOUT, stdin=subprocess.PIPE, stdout=f, shell=True)
    while True:
        command = input('Type:')
        if command == "cls":
            open('output.txt', 'w').close()
            os.system('cls' if os.name == 'nt' else 'clear')
        else:
            command = command.encode('utf-8') + b'\n'
            proc.stdin.write(command)
            proc.stdin.flush()
            with open('output.txt', 'r+') as ff:
                print(ff.read())
    

    You could maybe also not redirect the output to a text file...