Search code examples
pythonsubprocesspopen

Popen subprocessing problems


I'm trying to learn about the subprocessing module and am therefore making a hlds server administrator.

My goal is to be able to start server instances and send all commands through dispatcher.py to administrate multiple servers, e.g. send commands to subprocesses stdin.

what I've got so far for some initial testing, but got stuck already :]

#dispatcher.py
import subprocess

RUN = '/home/daniel/hlds/hlds_run -game cstrike -map de_dust2 -maxplayers 11'
#RUN = "ls -l" 

hlds = subprocess.Popen(RUN.split(), stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

print hlds.communicate()[0]

print hlds.communicate()[1]

hlds.communicate('quit')

I am not getting any stdout from the hlds server, but it works fine if i dont set stdout to PIPE. And the hlds.communicate('quit') does not seem to be sent to the hlds process stdin either. The ls -l command returns stdout correctly but not hlds.

All help appreciated! :)


Solution

  • See the Popen.communicate docs (emphasis mine):

    Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.

    So you can only call communicate once per run of a process, since it waits for the process to terminate. That's why ls -l seems to work -- it terminates immediately, while hlds doesn't.

    You'd need to do:

    out, error = hlds.communicate('quit')
    

    if you want to send in quit and get all output until it terminates.

    If you need more interactivity, you'll need to use hlds.stdout, hlds.stdin, and hlds.stderr directly.