简体   繁体   English

防止在Python中使用子流程创建新的子流程

[英]Prevent creating new child process using subprocess in Python

I need to run a lot of bash commands from Python. 我需要从Python运行很多bash命令。 For the moment I'm doing this with 目前,我正在与
subprocess.Popen(cmd, shell=True) subprocess.Popen(cmd,shell = True)

Is there any solution to run all these commands in the same shell? 有什么解决方案可以在同一shell中运行所有这些命令吗? subprocess.Popen opens a new shell at every execution and I need to set up all the necessary variables at every call, in order for cmd command to work properly. subprocess.Popen在每次执行时都会打开一个新的shell,为了使cmd命令正常工作,我需要在每次调用时都设置所有必需的变量。

subprocess.Popen lets you supply a dictionary of environment variables, which will become the environment for the process being run. subprocess.Popen允许您提供环境变量的字典,它将成为正在运行的进程的环境。 If the only reason you need shell=True is to set an environment variable, then I suggest you use an explicit environment dictionary instead; 如果需要shell=True的唯一原因是设置环境变量,则建议您改用显式环境字典; it's safer and not particularly difficult. 它更安全,也不是特别困难。 Also, it's usually much easier to construct command invocations when you don't have to worry about quoting and shell metacharacters. 同样,当您不必担心引用和shell元字符时,通常更容易构造命令调用。

It may not even be necessary to construct the environment dictionary, if you don't mind having the environment variables set in the running process. 如果您不介意在运行的进程中设置环境变量,则甚至不需要构造环境字典。 (Most of the time, this won't be a problem, but sometimes it is. I don't know enough about your application to tell.) (在大多数情况下,这不是问题,但有时是问题。我对您的应用程序了解不足,无法告诉。)

If you can modify your own environment with the settings, just do that: 如果可以使用设置修改自己的环境,请执行以下操作:

os.environ['theEnvVar'] = '/the/value' 

Then you can just use a simple Popen.call (or similar) to run the command: 然后,您可以使用简单的Popen.call (或类似方法)运行命令:

output = subprocess.check_output(["ls", "-lR", "/tmp"])

If for whatever reason you cannot change your own environment, you need to make a copy of the current environment, modify it as desired, and pass it to each subprocess.call : 如果出于某种原因您无法更改自己的环境,则需要制作当前环境的副本,根据需要对其进行修改,然后将其传递给每个subprocess.call

env = os.environ.copy()
env['theEnvVar'] = '/the/value'
output = subprocess.check_output(["ls", "-lR", "/tmp"], env=env)

If you don't want to have to specify env=env every time, just write a little wrapper class. 如果您不想每次都指定env=env ,只需编写一个包装器类即可。

Why not just create a shell script with all the commands you need to run, then just use a single subprocess.Popen() call to run it? 为什么不只使用需要运行的所有命令来创建shell脚本,然后仅使用单个subprocess.Popen()调用来运行它? If the contents of the commands you need to run depend on results calculated in your Python script, you can just create the shell script dynamically, then run it. 如果您需要运行的命令的内容取决于Python脚本中计算的结果,则可以仅动态创建Shell脚本,然后运行它。

Use multiprocessing instead, it's more lightweight and efficient. 而是使用多处理 ,它更轻便,更有效。

Unlike subprocess.Popen it does not open a new shell at every execution. 与subprocess.Popen不同,它不会在每次执行时都打开新的shell。

You didn't say you need to run subprocess.Popen and you may well not need to; 您并没有说您需要运行subprocess.Popen ,您可能不需subprocess.Popen you just said that's what you're currently doing. 您刚刚说的就是您目前正在做的事情。 More justification please. 请提供更多理由。

See set env var in Python multiprocessing.Process for how to set your env vars once and for all in the parent process. 有关如何在父进程中一劳永逸地设置环境变量的信息,请参见Python multiprocessing.Process中的set env var

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM