如何使用python中的子进程将两个值传递给stdin

时间:2014-03-18 00:34:09

标签: python subprocess

我正在执行一个脚本,它一个接一个地提示2个值。我想从脚本本身传递值,因为我想自动执行此操作。

使用子进程模块,我可以轻松传递一个值:

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 个答案:

答案 0 :(得分:2)

你应该使用\ n代替/ r / n - > ' Y \ n密码'

由于你的问题不明确,我假设你的程序有点像这个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"),然后要求您输入密码。在那之后,它确实有用#34;最后输出密码然后退出

现在要让第一个程序由第二个脚本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")

此案例告诉您,无论如何通过脚本传递密码可能不是一个好主意。

另外请记住,使用shell = True选项调用subprocess.Popen通常也是一个坏主意。使用shell = False并将命令提供为参数列表:

cmd_suppression=["python","./testscript2.py"]
process=subprocess.Popen(cmd_suppression,shell=False,\
stdin=subprocess.PIPE,stdout=subprocess.PIPE)

Subprocess文档

中提到了十几次

答案 1 :(得分: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)

注意:子脚本可能直接从终端请求密码而不使用子进程'stdin / stdout。在这种情况下,您可能需要pexpectpty个模块。见Q: Why not just use a pipe (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)