如何使用子进程在当前激活的virtualenv中运行python代码?

had*_*adi 3 python subprocess virtualenv

我有一个名为 virtualenv 的虚拟环境'venv',它已激活:

(venv)>
Run Code Online (Sandbox Code Playgroud)

我编写了将在 virtualenv ( main.py) 中运行的代码:

import subprocess
result = subprocess.run('python other.py', stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

但是当我运行main.py文件时:

(venv)> python main.py
Run Code Online (Sandbox Code Playgroud)

subprocesspython other.py不在virtualenv ie 中执行命令 ( )venv

如何subprocess在当前virtualenv会话中运行命令?

Cha*_*ffy 5

如果没有父进程的参与,子进程无法在其父进程中运行命令。

例如,这就是为什么ssh-agent需要使用它来调用它在输出上发出的 shell 命令。eval "$(ssh-agent -s)"因此,您在这里要求的字面意思是不可能的。

幸运的是,这也是不必要的。


virtualenvs 使用子进程继承的环境变量。

这意味着您实际上不需要使用激活了 virtualenv 的同一个 shell 来启动旨在使用解释器/库/等的新 Python 解释器。来自该 virtualenv。


subprocess.run必须传递一个列表,或者shell=True必须使用。

要么这样做(更好!)

import subprocess
result = subprocess.run(['python', 'other.py'], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

或者这个(更糟糕!)

import subprocess
result = subprocess.run('python other.py', stdout=subprocess.PIPE, shell=True)
Run Code Online (Sandbox Code Playgroud)

  • @hadi 它可以很容易地打开安全漏洞。例如,如果您使用以下代码: `import subprocess;name = input("Name? ");subprocess.run(f"echo Hi, {name}", shell=True)` 那么有人可以告诉用户输入`person;sudo rm -Rf /*` 作为他们的名称,这将是一个有效的命令,因为放在一起的整个字符串是 `echo person;sudo rm -Rf /*` (UNIX 中的 sudo rm -Rf /* 将删除每个文件可能在计算机上递归)。他们不能使用 `shell=False` 来做到这一点,因为它实际上并不是在 shell 中运行,所以这种情况不会发生。 (2认同)