命令行和subprocess.call之间的标准输入不一致

时间:2015-04-13 21:19:38

标签: python subprocess stdin

我想创建一个文件,用作python脚本的标准输入,并使用subprocess.call调用所述脚本。

当我在命令行中直接执行它时,它可以正常工作:

输入文件:

# test_input
1/2/3

python脚本

# script.py
thisDate = input('Please enter date: ').rstrip()

以下命令可以正常工作:

python script.py < test_input

但是当我尝试在另一个python脚本中执行以下操作时,它不起作用。 (来自this

outfile1 = open('test_input', 'w')
outfile1.write('1/2/3')
outfile1.close()

input1 = open('test_input')
subprocess.call(['python', 'script.py'], stdin=input1)

但后来我收到以下错误:

>>>thisDate = input('Please enter date: ').rstrip()
>>>AttributeError: 'int' object has no attribute 'rstrip'

当我进行一些调试时,它似乎是将整数0作为输入。

造成这种不一致的原因是什么?这两种方法不相同(显然它们不是,但为什么)?我的最终目标是执行与上述命令行版本完全相同的任务。

谢谢

4 个答案:

答案 0 :(得分:1)

您正在使用inputraw_input时,{python2中的inputeval字符串。如果您使用python3运行脚本,它将按原样运行,python2更改为raw_input

使用check_call通常是一种更好的方法,并使用with打开您的文件。

import subprocess
with open('test_input') as input1:
    subprocess.check_call(['python3', 'script.py'], stdin=input1)

答案 1 :(得分:0)

所以chepner是正确的。当我修改以下行时:

subprocess.call(['python', 'script.py'], stdin=input1)

为:

subprocess.call(['python3', 'script.py'], stdin=input1)

它运作得很好。

(我试图在python3中这样做)

答案 2 :(得分:0)

在第一个实例中,文件有两行,input()读取并解析第一行,这是一个注释。

在第二种情况下,缺少注释行,因此Python会读取并解析一个数字。

您可能打算使用raw_input(),或者使用Python 3运行脚本。

(您可能还意味着输入文件以换行符结束,当您运行Python时,使用subprocess.call()运行Python并没有多大意义。)

答案 3 :(得分:0)

python script.py < test_input命令应该失败。您可能需要:python3 script.py < test_input,而不是由于其他答案中提到的Python 2上input()raw_input()之间的差异。 python as a rule指的是Python 2版本。

如果仅使用python3运行脚本,则可以使用sys.executable使用相同的python版本运行子脚本(相同的可执行文件) ):

#!/usr/bin/env python3
import subprocess
import sys

with open('test_input', 'rb', 0) as input_file:
    subprocess.check_call([sys.executable or 'python3', 'script.py'],
                          stdin=input_file)

如果父母和孩子可以使用不同的python版本,那么在script.py中设置正确的shebang,例如#!/usr/bin/env python3并直接运行脚本:

#!/usr/bin/env python
import subprocess

with open('test_input', 'rb', 0) as input_file:
    subprocess.check_call(['./script.py'], stdin=input_file)

这里,子脚本可以选择自己的python版本。确保脚本具有可执行权限:chmod +x script.py。注意:Python Launcher for Windows也理解shebang语法。

无关:使用.communicate()代替outfile1.write('1/2/3')

#!/usr/bin/env python3
from subprocess import Popen, PIPE

with Popen(['./script.py'], stdin=PIPE, universal_newlines=True) as p:
    p.communicate('1/2/3')