如何通过Python的subprocess将两个值传递给stdin
我正在运行一个脚本,这个脚本会依次提示输入两个值。我想要在脚本内部直接传入这两个值,因为我想要自动化这个过程。
通过使用subprocess模块,我可以很容易地传入第一个值:
suppression_output = subprocess.Popen(cmd_suppression, shell=True,
stdin= subprocess.PIPE,
stdout= subprocess.PIPE).communicate('y') [0]
但是传入第二个值似乎不太成功。如果我这样做:
suppression_output = subprocess.Popen(cmd_suppression, shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE).communicate('y/r/npassword')[0]
2 个回答
1
试试 os.linesep
:
import os
from subprocess import Popen, PIPE
p = Popen(args, stdin=PIPE, stdout=PIPE)
output = p.communicate(os.linesep.join(['the first input', 'the 2nd']))[0]
rc = p.returncode
在 Python 3.4 及以上版本中,你可以使用 check_output()
:
import os
from subprocess import check_output
input_values = os.linesep.join(['the first input', 'the 2nd']).encode()
output = check_output(args, input=input_values)
注意:子脚本可能会直接从终端请求密码,而不是通过 subprocess 的输入输出。在这种情况下,你可能需要使用 pexpect
或 pty
模块。可以查看 问:为什么不直接使用管道 (popen())?
import os
from pexpect import run # $ pip install pexpect
nl = os.linesep
output, rc = run(command, events={'nodes.*:': 'y'+nl, 'password:': 'test123'+nl},
withexitstatus=1)
2
你应该使用 \n 来表示换行,而不是 /r/n -> 'y\npassword'
因为你的问题不太清楚,我假设你有一个程序,它的行为有点像这个 Python 脚本,我们叫它 script1.py:
import getpass
import sys
firstanswer=raw_input("Do you wish to continue?")
if firstanswer!="y":
sys.exit(0) #leave program
secondanswer=raw_input("Enter your secret password:\n")
#secondanswer=getpass.getpass("Enter your secret password:\n")
print "Password was entered successfully"
#do useful stuff here...
print "I should not print it out, but what the heck: "+secondanswer
这个程序会先询问你确认("y"),然后让你输入密码。之后它会做一些“有用的事情”,最后打印出密码,然后退出。
现在,如果你想让第二个脚本 script2.py 来运行第一个程序,它的结构大概应该是这样的:
import subprocess
cmd_suppression="python ./testscript.py"
process=subprocess.Popen(cmd_suppression,shell=True\
,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
response=process.communicate("y\npassword")
print response[0]
script2.py 的输出:
$ python ./script2.py
Do you wish to continue?Enter your secret password:
Password was entered successfully
I should not print it out, but what the heck: password
如果这个程序使用了一种特殊的方法来安全地获取密码,那么就可能会出现问题,也就是说,如果它使用了我刚刚在 script1.py 中注释掉的那行代码:
secondanswer=getpass.getpass("Enter your secret password:\n")
这种情况下,传递密码通过脚本可能不是个好主意。
另外,记得使用 subprocess.Popen 时,设置 shell=True 通常也是个坏主意。应该使用 shell=False,并把命令作为参数列表提供:
cmd_suppression=["python","./testscript2.py"]
process=subprocess.Popen(cmd_suppression,shell=False,\
stdin=subprocess.PIPE,stdout=subprocess.PIPE)
在 Subprocess 文档中提到过很多次。