0

I'm looking for a python module that provides a TRUE interactive os shell (in Linux, win, & mac os) via the STDIO. I've tried various examples using subprocess+PIPES and/or QProcess to start csh/bash or cmd.exe and then provide a crude terminal IO via QTextEdit keyPressEvents. This works ok for basic os commands but if I want to start another app within the shell process (ex. telnet, ssh, tcl, python, netstat, etc., etc.) stdin and stdout are no longer attached, probably due to a new child process being created. Will I have to subprocess/QProcess each command and keep track of all the child processes? -- that's going to be ugly, there has to be a better way... (I have also looked at pexpect/wexpect but couldn't get it working reliably.)

Environment: Win7, RHEL6.4, Python 2.7.8, Qt 4.8.6

It seems like the requested module would be part of a standard PyQt library; am I missing something? Perhaps there's not much of a need for a true interactive os shell within python.

Sample snippet of crude shell terminal:

class Console(QtGui.QTextEdit):
 def __init__(self, startup_message='', parent=None):
    super(Console, self).__init__(parent)

    . . .

    # TextEdit settings
    self.setAcceptRichText(True)

    #QProcess setup
    self.proc = QtCore.QProcess()
    self.proc.setProcessChannelMode(QtCore.QProcess.MergedChannels)
    self.proc.setReadChannelMode(QtCore.QProcess.MergedChannels)
    QtCore.QObject.connect(self.proc, QtCore.SIGNAL("readyReadStandardOutput()"), self.procReadStdOutput)

    . . .

    if sys.platform == "win32":
        self.proc.start(r"cmd.exe", mode=QtCore.QProcess.ReadWrite)
    elif sys.platform == "linux2":
        self.proc.start(r"csh", mode=QtCore.QProcess.ReadWrite)

    . . .

 def runCommand(self):
    if self.userTextEntry != "":
        self.userCommand = self.userTextEntry
        self.userTextEntry = ""
        try:
            self.proc.writeData(self.userCommand)
        except Exception as error:
            self.append(str(error))
    else:
        self.append(self.prompt)
    return

. . .

 def keyPressEvent(self, event):
    if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
        event.accept()
        self.userTextEntry += "\n"
        self.runCommand()
    . . .


 @QtCore.pyqtSlot()
 def procReadStdOutput(self):
    self.append(QtCore.QString(self.proc.readAllStandardOutput()))
    self.append(self.getOSPrompt())
    self.proc.emit(QtCore.SIGNAL("cmdDone()"))
    return
bbtexas
  • 1
  • 2
  • 1
    Is there something you want that isn't covered by simply launching a terminal emulator via `subprocess`? – chepner Sep 09 '14 at 14:57
  • The idea is to have a true interactive os shell within a Python program. Problems arise when certain os cmds or apps are launched inside the subprocess'ed shell (a simple example is to subprocess csh and send 'more myfile' from the term emu). Typically the IO is lost either due to a new process or block buffering vs. line buffering; I'm not sure. Or maybe this is just a term emulator implementation issue - if so, a sample solution would be nice. Certainly, any shell commands or apps that are launched must have their IO redirected so that I can send & receive data from the QTextEdit window. – bbtexas Sep 10 '14 at 14:31
  • Do you really need a shell within the PyQt4 interface? What about `os.system('gnome-terminal')`? You can do the job in the emerging terminal, close it when you finished and then come back to your gui. – a_guest Sep 15 '14 at 12:36
  • Or as you seem to use window this would change to `os.system('cmd')` but this does not give a pop-up terminal (in contrast to linux) but a new session within the terminal you are running your program in. Window focus is not changed automatically. But since you are using Windows maybe you know a command how to open a new terminal from the command line. If not this new session in the previous terminal is anyway a common interactive os shell which you can `exit` normally etc. i.e. that should meet you needs. – a_guest Sep 15 '14 at 16:23
  • The need is to have an interactive shell whose terminal interface goes thru the Qt gui widget (QTextEdit in this case). The idea is to eventually perform Python operations on document data in QTextEdit (among other things). I welcome any other ideas/examples... – bbtexas Sep 26 '14 at 21:36

0 Answers0