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

Standard input inconsistency between command line and subprocess.call

我想创建一个文件,用作 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 作为输入。

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

谢谢

您在使用 input 时应该是 raw_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)

所以切普纳是正确的。当我修改以下行时:

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

至:

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

它工作得很好。

(我正在尝试在 python3 中执行此操作)

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

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

您可能打算使用 raw_input(),或 运行 带有 Python 的脚本 3.

(您可能还意味着输入文件以换行符结尾,并且当您已经使用 subprocess.call() 到 运行 Python 运行宁Python.)

python script.py < test_input 命令应该会失败。您的意思可能是:python3 script.py < test_input 而不是由于 input() 与 Python 2 上的 raw_input() 之间的差异,如其他答案中所述。 python as a rule指的是Python2版本。

如果 parent 脚本 运行 仅使用 python3 那么您可以使用 sys.executable 到 运行 child 脚本使用相同的 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)

如果 parent 和 child 可能使用不同的 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)

此处,child 脚本可以选择自己的 python 版本。确保脚本具有可执行权限:chmod +x script.py。注意:Python 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')