Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python在不同的virtualenv中运行子流程_Python_Virtualenv - Fatal编程技术网

使用python在不同的virtualenv中运行子流程

使用python在不同的virtualenv中运行子流程,python,virtualenv,Python,Virtualenv,假设我在两个不同的虚拟环境中安装了两个不同版本的应用程序。myapp v1.0和myapp v2.0 现在我想比较一下。比较是用python本身编写的。最好的方法是什么?让我们假设我可以分别运行它们,并编写一个输出文件,稍后可以进行比较 一种方法是编写bash脚本(这就是我目前拥有的)。我激活一个virtualenv,运行myapp v1.0,激活另一个virtualenv,运行myapp v2.0。稍后对这些文件运行比较模块。但是我想在这里添加更多的动态(采用一些可选参数等),这将更容易使用p

假设我在两个不同的虚拟环境中安装了两个不同版本的应用程序。myapp v1.0和myapp v2.0

现在我想比较一下。比较是用python本身编写的。最好的方法是什么?让我们假设我可以分别运行它们,并编写一个输出文件,稍后可以进行比较

一种方法是编写bash脚本(这就是我目前拥有的)。我激活一个virtualenv,运行myapp v1.0,激活另一个virtualenv,运行myapp v2.0。稍后对这些文件运行比较模块。但是我想在这里添加更多的动态(采用一些可选参数等),这将更容易使用python

编辑:

目前我有类似的东西(bash脚本):

相反,我只想做:

python my_comparison_script.py

我的脚本将在这里面运行。

问题到底是什么?如何使用子流程执行shell命令?如果是这种情况,一些过于简单的伪代码可能如下所示:

import subprocess

myProcess = subprocess.Popen(   ['these', 'are', 'for', 'the', 'shell'],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE )

[outStream, errStream] = myProcess.communicate()
import subprocess

with open('dateHelp.log', 'w') as dateLog:
    with open('dateHelp.err', 'w') as errLog:
        dateHelp = subprocess.Popen([ 'date', '-h'], stdout=dateLog, 
                                                     stderr=errLog)
        dateHelp.communicate()
然后,您可以使用standard out(
outStream
)执行任何您想执行的操作,如果存在
errStream
(标准错误),则可以执行不同的操作。这包括将标准输出或标准错误写入文件。那么我想你会把那些文件分开

实际的代码示例(假设您在linux系统上有python 2.6+)可能如下所示:

import subprocess

myProcess = subprocess.Popen(   ['these', 'are', 'for', 'the', 'shell'],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE )

[outStream, errStream] = myProcess.communicate()
import subprocess

with open('dateHelp.log', 'w') as dateLog:
    with open('dateHelp.err', 'w') as errLog:
        dateHelp = subprocess.Popen([ 'date', '-h'], stdout=dateLog, 
                                                     stderr=errLog)
        dateHelp.communicate()

被接受的答案并没有解决在子流程中“激活”virtualenv的问题

如果您通过调用python可执行文件启动应用程序,就像在您的示例中一样,它实际上非常简单:您只需显式地指向virtualenv中的可执行文件

导入子流程
Popen([“virtualenv1/bin/python”,“my_script.py”])
Popen([“virtualenv2/bin/python”,“my_other_script.py”])
将在相应的VirtualNV中启动进程

重要

为解决评论中提出的问题:

如果要运行子进程并确保使用当前进程正在运行的同一解释器,则必须使用该解释器。也可用:访问安装平台相关Python文件的特定于站点的目录前缀


如果您想对此主题进行更深入的讨论,请看一看。

一个简单的选择是运行一系列带有子流程的命令,如下所示(请注意,“shell=True”有风险,只有在您可以控制输入的情况下才应使用)


并根据需要重复。

我认为virtualenv文档很好地解释了这一点

TL;DR

直接运行python venv二进制文件与激活venv不同。 您还必须相应地更改路径和虚拟环境变量(查看)

$source/path/to/ENV/bin/activate

这将更改您的$PATH,因此它的第一个条目是virtualenv的 bin/目录。(您必须使用source,因为它会更改您的shell 这就是它所做的一切;这纯粹是一种方便

如果直接从 virtualenv的bin/目录(例如path/to/ENV/bin/pip或 /path/to/ENV/bin/python script.py),则sys.path将自动 设置为使用与virtualenv关联的Python库。但是 与激活脚本不同,环境变量PATH和 不会修改虚拟环境。这意味着如果您的Python 脚本使用子流程运行另一个Python脚本(例如通过 !/usr/bin/env python shebang line)第二个脚本不能使用与第一个脚本相同的python二进制文件执行,也不能使用相同的 它可以使用的图书馆。要避免这种情况发生,请使用您的第一个脚本 将需要以与相同的方式修改环境变量 激活脚本,然后执行第二个脚本


我也可以通过这种方式激活我的VirtualNV吗?我的问题是,如何在不同的VirtualNV中运行进程。但我想我可以用一个进程激活virtualenv,然后执行依赖于virtualenv的脚本?不过谢谢你的例子。我不确定你是如何正常激活你的VirtualNV的,但我想你可以用子流程来激活它。更好的是,如果已经编写了bash脚本,为什么不使用python来包装这些脚本呢?子流程可以调用这些脚本并以相同的方式处理它们的输出。如果希望python脚本具有不同的模式,可以使用argparse或optparse(取决于您的版本)设置python脚本/venv1/bin/activate&&python你的_-app.py并使用
shell=TRUE
运行它,以在子流程中使用
venv1
运行
你的_-app.py
。@NoufalIbrahim有点差劲(不安全)但是您必须使用shell=True。@AndyHayden只有在命令是由不受信任的输入构造的情况下,通过shell启动命令才是不安全的。实际上,这还不够。激活virtualenv也会改变一些环境变量,调用特定的virtualenv的python并不能做到这一点。结果,将加载错误的库。@qarma:我不同意-这种方法有效,我正在自己的生产代码中使用它。我也是。如果您具体化所引用的环境变量,并提供一个测试用例,说明在何种情况下会加载错误的库,我会很有帮助。是的,我在virtualenv的网站上也看到了这一建议。至少有两种情况下,直接使用virtualenv链接的python解释器运行与使用activate不同:当设置了
PYTHONHOME
时,以及当目标程序使用
command
Popen
运行另一个python程序时。我刚刚尝试了第二种场景,这是真的:从我的_script.py内部调用子流程将由syst执行