我试图用Python编译一个C程序,想给予“〈”操作符输入,但它没有按预期工作。如果我编译C程序,并通过文件输入来运行它,它就能工作;例如
./a.out <inp.txt works
但同样,如果我尝试使用Python脚本执行此操作,结果并不完全符合预期。
import subprocess
subprocess.call(["gcc","a.c","-o","x"])
subprocess.call(["./x"])
以及
import subprocess
subprocess.call(["gcc","a.c","-o","x"])
subprocess.call(["./x","<inp.txt"])
两个脚本都要求通过终端输入。但是我认为在第二个脚本中它应该从文件中读取。为什么两个程序的工作方式是一样的?
3条答案
按热度按时间ruarlubt1#
作为对乔纳森·莱弗勒和阿拉斯泰尔有益回答的补充:
假设 you 控制着要传递给shell执行的字符串,我认为使用shell来方便没有什么错。[1]
subprocess.call()
有一个可选的布尔shell
参数,该参数会将命令传递给 shell,从而启用I/O重定向、引用环境变量......:注意整个命令行是如何作为 * 单个 * 字符串而不是参数数组传递的。
[1]避免在以下情况下使用shell:
如果您担心shell环境缺乏可预测性(如@alastair):
subprocess.call
与shell = True
***总是 * 创建/bin/sh
**的非交互式非登录示例-请注意,使用的不是 * 用户的 * 默认shell。sh
不读取非交互式非登录shell(既不是系统范围的也不是用户特定的shell)的初始化文件。sh
伪装成bash
的平台上,bash
在作为sh
调用时也会这样做。shell = True
创建的每个shell示例都是自己的世界,其环境既不受以前的shell示例的影响,也不影响以后的shell示例。一般来说,这是一个 * 特性,因为Python(CPython)本身被设计成可以通过环境变量来控制(对于Python 2.x,请参见https://docs.python.org/2/using/cmdline.html#environment-variables;对于3.x版本,请参见)。
如果需要,您可以通过
env
参数向shell * 提供您自己的环境;但是请注意,您必须在该事件中提供 * 整个 * 环境,如果需要,可能包括USER
和HOME
等变量;简单示例,明确定义$PATH
:bqjvbblv2#
shell为一个进程做I/O重定向。根据你所说的,
subprocess
模块不做这样的I/O重定向。为了演示,运行:这将运行shell,并应重定向I/O。在您的代码中,您的程序
./x
被给定了一个参数<inp.txt
,它将忽略该参数。注意:对
subprocess.call
的替代调用纯粹是出于诊断目的,而不是推荐的解决方案,推荐的解决方案包括阅读(Python 2)subprocess模块文档(或Python 3模块文档),以了解如何使用该模块进行重定向。如果您的脚本即将退出,这样您就不必担心浪费文件描述符,您可以将其压缩为:
vhipe2zx3#
默认情况下,
subprocess
模块不向shell传递参数,为什么呢?因为通过shell运行命令是 * 危险的 *;除非它们被正确地引用和转义(这很复杂),否则通常有可能使执行此类操作的程序运行不需要的和意外的shell命令。无论如何使用shell都是错误的,如果你想从一个特定的文件中获取输入,你可以使用
subprocess.Popen
,将stdin
参数设置为inp.txt
文件的文件描述符(你可以通过调用fileno()
这个Python文件对象来获得文件描述符)。