如何将命令发送到已作为子进程打开的CLI?

时间:2014-07-03 10:54:54

标签: python python-2.7 ubuntu subprocess

我需要一些帮助。我想要做的是用python程序打开一个子进程,然后让子进程在程序的某些点执行特定的命令。让我试着通过一个非常简单的代码片段来说明我的问题:

import subprocess
import time

#create a new terminal
cmd = ["gnome-terminal --window &"]
process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)

#do something else
time.sleep(5)

#and now I want to execute a command in the new terminal 

首先,我很高兴看到像lsifconfig这样的简单命令。只是在新终端中放置一些文本以确认它是否有效。

我原本希望Popen.communicate(input)可以做到这一点,就像process.communicate("ls")那样,但到目前为止它似乎无效。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您可能希望查看pexpect模块 - 它专为此目的而设计,包括查找子进程中的特定提示和错误。

我编写的脚本中的一个简单(简化)示例。它使用ssh会话登录并在服务器上运行脚本。

import pexpect

server = "server.home" # normally passed as arguments
display = 1            # normally passed as arguments

ssh = pexpect.spawn("ssh", ["{0}".format(server), "~/vnc.py", "{0}".format(display)])
try:
    index = ssh.expect("^.*password:")
except:
    print "Have not received password prompt from {host} - server down or ssh not enabled".format(host=server)
    sys.exit(1)

if index == 0:   
    ssh.sendline( password )
else:
    print "Unable to communicate with server"

非常有用,特别是如果您有复杂的互动。

BTW完整脚本是一组自制脚本,允许我在远程服务器上启动VNC服务器(作为打印服务器运行),然后将vnc查看器记录到VNC服务器上。

答案 1 :(得分:0)

这是一个适用于Windows的功能。也许它有帮助...

Popen.communicate正在制定流程并在其中返回stdout的结果。我只能打电话一次。如果我想发送多个命令,我需要将它们放在一个字符串中并在每个命令之后添加\ n。

## @ingroup cliFunc
#  @brief run a commandline inside a shell
#
#  run a command in a console and return it's output
#
#  @param command   :[\b string] commandline to execute
#  @param tempDir   :[\b string][\em optional] directory to run the command
#  @return           [\b string] a string with the output
def runCommandStdOut(command, tempDir = None):
    # redirect standard output (including the print statement)
    # creationflags for windows
    # CREATE_NO_WINDOW = 0x08000000
    p = sp.Popen("cmd.exe /X/D/F:ON", stdin=sp.PIPE,
                    stdout=sp.PIPE, stderr=sp.STDOUT, creationflags=0x08000000)
    flag = "(@@@@@@}"
    cmand = "PROMT"+flag+'\n'

    if tempDir:
    cmand +=  "cd " + tempDir +"\n"


    cmand += command
    return p.communicate(cmand+"\n")[0]