使用Python子进程命令调用C编译器

Vip*_*pul 2 c python shell

我正在尝试使用Python编译一个C程序,并希望使用"<"运算符进行输入,但它没有按预期工作.如果我编译C程序并通过提供输入来运行它,它可以工作; 例如

./a.out <inp.txt works
Run Code Online (Sandbox Code Playgroud)

但同样地,如果我尝试使用Python脚本执行此操作,那么它并没有像预期的那样完成.例如:

import subprocess
subprocess.call(["gcc","a.c","-o","x"])
subprocess.call(["./x"])
Run Code Online (Sandbox Code Playgroud)

import subprocess
subprocess.call(["gcc","a.c","-o","x"])
subprocess.call(["./x","<inp.txt"])
Run Code Online (Sandbox Code Playgroud)

两个脚本都要求终端输入.但我认为在第二个脚本中它应该从文件中读取.为什么两个程序都一样?

mkl*_*nt0 5

补充@Jonathan Leffler@ alastair 有用答案:

假设控制了传递给shell执行的字符串,我认为使用shell是为了方便.[1]

subprocess.call()有一个可选的布尔shell参数,它导致命令传递给shell,启用I/O重定向,引用环境变量,......:

subprocess.call("./x <inp.txt", shell = True)
Run Code Online (Sandbox Code Playgroud)

请注意整个命令行如何作为单个字符串而不是参数数组传递.


[1] 在下列情况下避免使用shell:

  • 如果你的Python代码必须在平台上运行的其他类Unix的那些,如Windows.
  • 如果表现至关重要.
  • 如果你发现自己在Python方面更好地处理"外包"任务.

如果您担心shell环境缺乏可预测性(如@alastair所示):

  • subprocess.callwith shell = True 始终创建非交互式非登录实例/bin/sh - 请注意,它不是用户使用的默认shell.
  • sh 不读取非交互式非登录shell的初始化文件(既不是系统范围的也不是用户特定的).
    • 请注意,即使在平台上哪里shbash在伪装,bash当作为调用将这样的行为sh.
  • subprocess.callwith 创建的每个shell实例shell = True都是它自己的世界,它的环境既不受以前的shell实例的影响,也不影响以后的实例.
  • 但是,创建shell实例确实继承了python进程本身环境:
    • 如果从交互式shell启动Python程序,则继承该shell的环境.请注意,这仅适用于当前工作目录环境变量,而不适用于别名,shell函数和shell变量.
    • 一般来说,这是一个特性,因为Python(CPython)本身可以通过环境变量进行控制(对于2.x,请参阅https://docs.python.org/2/using/cmdline.html#environment-variables ;对于3.x,请参阅https://docs.python.org/3/using/cmdline.html#environment-variables).
    • 如果需要,您可以通过env参数为shell 提供自己的环境 ; 但是,请注意,您必须在该事件中提供整个环境,可能包括变量,如USERHOME,如果需要; 简单示例,明确定义$PATH:
    • subprocess.call('echo $PATH', shell = True, \ env = { 'PATH': '/sbin:/bin:/usr/bin' })