Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何向已作为子进程打开的CLI发送命令?_Python_Python 2.7_Ubuntu_Subprocess - Fatal编程技术网

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

Python 如何向已作为子进程打开的CLI发送命令?,python,python-2.7,ubuntu,subprocess,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

我需要一些帮助。我试图做的是用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 
首先,我很高兴看到一个简单的命令,如
ls
ifconfig
工作。只是在新终端中放入一些文本以确认其工作

我曾希望
Popen.communicate(input)
能起到作用,即遵循
process.communicate(“ls”)
的思路,但到目前为止它似乎不起作用


任何帮助都将不胜感激。

这里有一个在windows上运行的函数。也许会有帮助

communicate正在协调进程并在其结果中返回stdout。我只能叫它一次。如果我想发送多个命令,我需要将它们放在一个字符串中,并在每个命令之后添加

## @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]

您可能希望查看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"
非常有用,尤其是当您有复杂的交互时


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

感谢您的回答,但根据我的说法,我应该使用“通信”而不是“标准输入”,或者?警告:请使用communicate()而不是.stdin.write、.stdout.read或.stderr.read,以避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致死锁。是的,我已经更新了我的示例。也可以工作,并避免文档中提到的阻塞。我建议在“ls”之后添加\n。