繁体   English   中英

从 windows 任务计划程序在虚拟环境中运行 python 脚本

[英]Run a python script in virtual environment from windows task scheduler

我正在尝试通过 windows 任务计划程序设置重复性 Python 任务。

当我输入“python.exe”的路径并将脚本的路径作为参数提供给 windows 任务计划程序时,我取得了成功(请参见下面的屏幕截图)

Windows 任务调度程序

但是,我希望能够选择一个特定的虚拟环境来运行脚本。 我对 venv 了解不多,我通常通过打开 cmd 并在所需的虚拟环境目录中运行 Scripts\activate.bat 来使用它。

如何使用 windows 任务计划程序完成“每 24 小时在 venvxxx 中运行任务 x”?

使用以下命令创建批处理文件:

c:\__full_path_to_virtualenv__\Scripts\activate.bat && python __full_path_to_python_script__.py

&&表示如果command1成功完成,则运行command2

然后将该批处理文件设置为要运行的脚本。 您不需要在任务调度程序中设置任何其他参数(或者您可以在批处理文件中设置它们)并且可以脚本必须从特定目录读取/写入并使用相对路径时设置Start

这更冗长但很容易理解,而且 - 我发现最重要的 - 当你有很多脚本时,比使用 Windows 任务计划程序设置容易得多。 要创建另一个,您只需复制 .bat 文件并更改一行。

将其另存为 .bat 文件并在Actions > Start a Program > Program/Script:下指向它,不需要参数或“开始”。

set original_dir=%CD%
set venv_root_dir="C:\Python-Venvs\env-name"
cd %venv_root_dir%
call %venv_root_dir%\Scripts\activate.bat

python your_script.py <arg1> <arg2>

call %venv_root_dir%\Scripts\deactivate.bat
cd %original_dir%
exit /B 1

对于已安装的命令行程序,您可以将python your_script.py <arg1> <arg2> ...替换为<program name> <arg1> <arg2> ...

此外,在下一行添加另一个脚本很简单,而不是尝试将顺序脚本解析为 Task Scheduler 的单行脚本。

尽管上面 mx0 的答案似乎有效,但我已经设置了 Task Scheduler 以在启动时运行 Flask Web 应用程序。 在这种情况下,手动启动工作正常,但手动结束则不行。 结束任务会杀死设置虚拟环境的 cmd.exe 任务,但 python.exe 继续运行。

我发现有效的解决方案来自这篇 reddit 帖子,它跳过虚拟环境激活直接调用 python 可执行文件:

path\to\venv\Scripts\python.exe path\to\script.py

我不确定这会有多健壮,但至少以这种方式结束任务将结束 python.exe

我尝试使用 mx0 的答案,只要您的脚本不会花费太长时间来完成,它就可以正常工作。

我在任务调度程序中使用不同的方法而不是使用批处理文件:

在“程序/脚本”文本框中,您将路径设置为 Python 可执行文件(在我的情况下是在 virtualenv 文件夹中)。

“添加参数” => 只是您的 Python 脚本的名称( name.ppy )。

"Start in" => Python 脚本的完整路径(不带name.py )。

这样脚本运行并等到结束。

在此处输入图片说明

我的解决方案几乎与 mx0 相同,但我添加了一个额外的步骤来确保每次的环境参数。 编辑app_path变量的path/to/app

每次检查环境设置可能有点多余,但我喜欢确保我的环境设置好。

只需安排execute_app.bat文件或在 cmd 提示符下运行。 除非从 Anaconda 提示符运行,否则不需要停用命令。 如果您使用path/to/app的完整路径,则可以从任何目录执行此文件。 我还有一个 Linux 解决方案,在终端中使用下面的execute_app.sh文件。

此答案已被编辑以简化并使用变量使其更容易适应新项目。

应用结构:
app/bin/app.py
app/bin/execute_app.bat
app/env/requirements.txt

# execute_app.bat file
# windows solution

SETLOCAL
set app_path=path/to/app
set env_path=%app_path%/env
set activ=%env_path%/Scripts/activate.bat
set req=%env_path%/requirements.txt
set app=%app_path%/bin/app.py

py -m venv %env_path% && %activ% && python -m pip install --upgrade pip && pip install -r %req% && python %app%
ENDLOCAL
#!/bin/bash

# execute_app.sh file
# Linux solution

app_path='path/to/app'
env_path=$app_path'/env'
activ=$env_path'/bin/activate'
req=$env_path'/requirements.txt'
app=$app_path'/bin/app.py'

python3 -m venv $env_path &&
. $activ &&
python3 -m pip install --upgrade pip &&
pip install -r $req &&
python $app &&
deactivate

为这个问题选择的答案是不正确的。 如果您查看评论,就会发现问题所在。

我的回答基于@Nick P 的回答(目前排名第二)。 他的批处理文件可以工作,但如果您希望 Windows 任务计划程序报告任务已成功完成,您需要将退出代码从 1 更改为 0。 此外,仅在“程序/脚本”行调用 .bat 文件将不起作用。 相反,您需要将 shell 的名称作为要运行的“程序/脚本”(例如,cmd),然后将“/c name-of-batch-file.bat”放入“Add arguments(可选) ):“ 场地。 最后,将批处理文件的路径(减去文件名)放在“开始于(可选):”字段中。

它应该看起来像这样: Windows 任务计划程序编辑操作表单的屏幕截图

REM Windows batch script to run 1+ Python program/scripts, sequentially, within
REM their virtual environment. This can be called from Windows Task Scheduler.
        
set original_dir=%CD%

set venv_root_dir="C:\Users\myUsername\myProjects\nameOfProject"
        
cd %venv_root_dir%
        
call %venv_root_dir%\Scripts\activate.bat
        
python nameOfPythonProgram.py
        
call %venv_root_dir%\Scripts\deactivate.bat
        
cd %original_dir%
    
exit /B 1

从 github 上的 nmpowell 复制了这个,它工作正常。 从任务调度程序运行

创建 bat 文件以启动 Python 脚本在启动进程时起作用,但在停止进程时不起作用。 当 taskengine.exe 决定停止作业时,bat 进程被终止,Python.exe 将被留下。

恕我直言,最好的方法是创建一个实用程序模块,例如patch_conda_path以基于 sys.base_exec_prefix 在 os.environ 中修补 PATH。
例如

import is, sys
conda_base = sys.base_exec_prefix
subps = [";", "library\\mingw-w64\\bin;", "library\\usr\\bin;", "library\\bin;", "scripts;", "bin;", "condabin;"]
conda_paths = ""
for p in subps :
    if p in os.environ["PATH"]:
        continue
    else:
        conda_paths += os.path.join(conda_base, p)
os.environ["PATH'"] = conda_paths + os.environ["PATH"]

在主脚本的最开始导入这个模块。 task scheduler program中的program设置为... conda path...\\python.exearguments为您的 py 脚本文件名,并start in您的 py 脚本文件夹开始。

这也适用于 conda3 中女服务员运行的烧瓶脚本。

暂无
暂无

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

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