我有我想从巨蟒(2.6.5)中运行的遵循以下逻辑的脚本:
- 提示用户输入密码。 看起来像(“请输入密码:)”)(*注:输入不回显到屏幕)
- 输出无关的信息
- 为响应提示用户( “等等等等FILENAME.TXT等等等等(Y / N)?:”)
最后提示行中包含的文字,我需要解析(FILENAME.TXT)。 提供不要紧响应(程序实际上可以在这里退出,而不提供一个,只要我能解析线)
我的要求是有点类似结束语在Python脚本交互式命令行应用程序 ,但反应似乎有一点混乱,即使在OP提到,它不是做他矿仍然挂起。
经过四处寻找,我得出这样的结论subprocess
是这样做的最佳方式,但我有一些问题。 这里是我的POPEN行:
p = subprocess.Popen("cmd", shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
当我调用read()
或readline()
在stdout
,提示是打印机的屏幕和它挂起。
如果我所说的write("password\n")
为stdin
,提示被写入屏幕,它挂起。 在文中write()
不写(我不移动光标的新行)。
如果我叫p.communicate("password\n")
相同的行为的write()
我在这里寻找一些想法的最佳方式输入到stdin
和可能,如果你的大方的感觉如何解析的最后一行输出,虽然我大概可以明白这一点,最终。
如果您正在使用子过程产生一个程序通信,你应该看看非阻塞读取Python中的subprocess.PIPE 。 我和我的应用程序有类似的问题,并使用队列是做一个子进程持续沟通的最佳途径找到。
至于从用户获取值,你可以随时使用的raw_input()内建得到响应,并为密码,尝试使用getpass
模块来从你的用户不呼应的密码。 然后,您可以分析这些答复,并将其写入到您的子标准输入。
最后我做一个类似于如下:
import sys
import subprocess
from threading import Thread
try:
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty # python 3.x
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()
def getOutput(outQueue):
outStr = ''
try:
while True: #Adds output from the Queue until it is empty
outStr+=outQueue.get_nowait()
except Empty:
return outStr
p = subprocess.Popen("cmd", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)
outQueue = Queue()
errQueue = Queue()
outThread = Thread(target=enqueue_output, args=(p.stdout, outQueue))
errThread = Thread(target=enqueue_output, args=(p.stderr, errQueue))
outThread.daemon = True
errThread.daemon = True
outThread.start()
errThread.start()
try:
someInput = raw_input("Input: ")
except NameError:
someInput = input("Input: ")
p.stdin.write(someInput)
errors = getOutput(errQueue)
output = getOutput(outQueue)
一旦你的队列制成,并且线程开始,你可以通过从用户获取输入,得到错误和输出过程中,处理并显示给用户环路。
使用线程可能是简单的任务略有矫枉过正。 相反os.spawnvpe可以使用。 这将产生脚本外壳作为一个过程。 您将可以用脚本进行交互式通信。 在这个例子中,我传递的密码作为参数,这显然是一个不好的主意。
import os
import sys
from getpass import unix_getpass
def cmd(cmd):
cmd = cmd.split()
code = os.spawnvpe(os.P_WAIT, cmd[0], cmd, os.environ)
if code == 127:
sys.stderr.write('{0}: command not found\n'.format(cmd[0]))
return code
password = unix_getpass('Password: ')
cmd_run = './run.sh --password {0}'.format(password)
cmd(cmd_run)
pattern = raw_input('Pattern: ')
lines = []
with open('filename.txt', 'r') as fd:
for line in fd:
if pattern in line:
lines.append(line)
# manipulate lines