Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling a terminal application with Python

I have a server program that runs through console. (Specifically, Bukkit MineCraft server) I'd like to be able to control this program and read the output. There is no GUI, so it shouldn't be too hard, right?

Anyway, I have never controlled a console in python and am totally stuck. Any suggestions?

P.S. I'm using Debian Linux, so that should simplify things a bit.

I've gotten a pretty good answer, but I also need one more thing. I want to have some way to print the FULL output of the program to the python console (Line by line is fine) and I need some way for commands in the console to be forwarded to the program.

like image 963
Eric Pauley Avatar asked Apr 19 '11 00:04

Eric Pauley


People also ask

How do you control a terminal in Python?

To change the terminal controls in the Unix system, we can use the tty related methods in Python. Using the tty module, we can set two different modes of the terminal. The raw Mode and the cbreak mode.

Can Python interact with terminal?

We can run Python files in the terminal as well. First, we need to make sure the current working directory is the one in which the file is located. We open a terminal and change the directory to "project-1" since the "today.py" file was saved in that directory.

What is a tty in Python?

Source code: Lib/tty.py. The tty module defines functions for putting the tty into cbreak and raw modes. Because it requires the termios module, it will work only on Unix.


2 Answers

The canonical answer for a task like this is to use Pexpect.

Pexpect is a Python module for spawning child applications and controlling them automatically. Pexpect can be used for automating interactive applications such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup scripts for duplicating software package installations on different servers. It can be used for automated software testing. Pexpect is in the spirit of Don Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python require TCL and Expect or require C extensions to be compiled. Pexpect does not use C, Expect, or TCL extensions. It should work on any platform that supports the standard Python pty module. The Pexpect interface focuses on ease of use so that simple tasks are easy.

like image 192
Greg Hewgill Avatar answered Sep 28 '22 22:09

Greg Hewgill


You can try to create an interactive shell inside python, something like:

import sys
import os
import subprocess
from subprocess import Popen, PIPE
import threading


class LocalShell(object):
    def __init__(self):
        pass
    def run(self):
        env = os.environ.copy()
        p = Popen('open -a Terminal -n', stdin=PIPE, stdout=PIPE, stderr=subprocess.STDOUT, shell=True, env=env)
        sys.stdout.write("Started Local Terminal...\r\n\r\n")

        def writeall(p):
            while True:
                # print("read data: ")
                data = p.stdout.read(1).decode("utf-8")
                if not data:
                    break
                sys.stdout.write(data)
                sys.stdout.flush()

        writer = threading.Thread(target=writeall, args=(p,))
        writer.start()

        try:
            while True:
                d = sys.stdin.read(1)
                if not d:
                    break
                self._write(p, d.encode())

        except EOFError:
            pass

    def _write(self, process, message):
        process.stdin.write(message)
        process.stdin.flush()
like image 20
Shawn Avatar answered Sep 28 '22 22:09

Shawn