Read text from os.Popen that opens new command prompt

Question:

I am using os.Popen to open a new command prompt window and run a process. How can I read the text within that command prompt. Please help.

import os

def OpenServers():
        os.chdir(coreServerFullPath)
        process=os.popen("start cmd /K CoreServer.exe -c -s").read()
        print(process) #Prints nothing

This is the output text that’s shown in the command prompt which I want to print.

Output text

EDIT:

I also tried this way, but no luck

 from subprocess import Popen, PIPE, STDOUT
 def OpenServers():
        os.chdir(coreServerFullPath)
        result = subprocess.Popen(['start', 'cmd', '/k', 'CoreServer.exe -c -s'], shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
        time.sleep(4)
        output=result.stdout.read()
        print(output) #Prints nothing

New Edit:

I tried something like this. Problem is, it makes me run 2 times. The first time when i run, the console is blank. The second time when I run it works but gives me an error because I can only open one instance of the server,.

def Test1():
        os.chdir(coreServerFullPath)
        result = subprocess.check_output(['CoreServer.exe', '-c', '-s'])
        print(result.stdout)

Here is the full code that I was trying. I can run CoreServer only as an admin so doing it like this

import os
import sys
import subprocess
from subprocess import Popen, CREATE_NEW_CONSOLE
from subprocess import Popen, PIPE, STDOUT
import time
import ctypes, sys

#The command prompts must be opened as administrators. So need to run the python script with elebvated permissions. Or else it won't work
def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

if is_admin():
    #The program can only run with elevated admin previlages.
    
    #Get the directory where the file is residing.
    currentDirectory=os.path.dirname(os.path.abspath(__file__))
    coreServerFullPath=os.path.join(currentDirectory,"CoreCoreServerServerCoreServer/binDebug")
    isExistCoreServer=os.path.exists(coreServerFullPath)

    echoServerFullPath=os.path.join(currentDirectory,"EchoServerEchoServer/binDebug")
    isExistEchoServer=os.path.exists(echoServerFullPath)

    #For now this is the MSBuild.exe path. Later we can get this MSBuild.exe as a standalone and change the path.
    msBuildPath="C:Program Files (x86)Microsoft Visual Studio/2019ProfessionalMSBuildCurrentBin/amd64"
    pathOfCorecsProjFile=os.path.join(currentDirectory,"CoreCoreServerServerCoreServerCoreServer.csproj")
    pathOfEchocsProjFile=os.path.join(currentDirectory,"EchoServerEchoServerEchoServer.csproj")


    def OpenServers():
        os.chdir(coreServerFullPath)
        #os.system("start /wait cmd /c {command}")
        command_line = [coreServerFullPath, '-c', '-s']
        result = subprocess.Popen(['start', 'cmd', '/k', 'CoreServer.exe -c -s'], shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
        time.sleep(4)
        output=result.stdout.read()
        print(output)
        #process=os.popen("start cmd /K CoreServer.exe -c -s").read()
        #print(process)

    def Test():
        os.chdir(coreServerFullPath)
        output = subprocess.check_output(['CoreServer.exe', '-c', '-s'],shell=True)
        time.sleep(4)
        print(output)
    
    def Test1():
        os.chdir(coreServerFullPath)
        result = subprocess.check_output(['CoreServer.exe', '-c', '-s'])
        print(result.stdout)


    if(not isExistCoreServer):
        if(os.path.isfile(pathOfCorecsProjFile)):
            os.chdir(msBuildPath)
            startCommand="start cmd /c"
            command="MSBuild.exe "+pathOfCorecsProjFile+" /t:build /p:configuration=Debug"
            #os.system(startCommand+command)
            cmd=subprocess.Popen(startCommand+command)

    if(not isExistEchoServer):
        if(os.path.isfile(pathOfEchocsProjFile)):
            os.chdir(msBuildPath)
            startCommand="start cmd /c"
            command="MSBuild.exe "+pathOfEchocsProjFile+" /t:build /p:configuration=Debug"
            os.system(startCommand+command)

    if(isExistCoreServer and isExistEchoServer):
        Test1()

else:
    # Re-run the program with admin rights
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
Asked By: nikhil

||

Answers:

For this type of situations the best way to get the output is to dump it to a log file and then read the output from the file. (Is better to create the log file before running the program)

Here you have a simple example:

result = subprocess.Popen('start cmd /k CoreServer.exe -c -s >> log.log 2>&1', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
time.sleep(4)
with open('log.log', 'r') as logg:
    print(logg.read())

This should print the desired output. Hope it works for you.

Answered By: kithuto
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.