GRAPES MESO模式学习笔记08-2 —— SMS中使用Python脚本

目录

现状

SMS通过SMSCMD变量设置的命令提交作业,默认是直接运行作业脚本

目前我们使用SMS执行作业有两种方式:

  1. 直接运行
  2. 通过loadleveler提交
    我们使用两个脚本实现上述功能
  3. 直接运行
    SMSCMD设置为

脚本lsbumit为

先创建SMSJOBOUT的目录(SMS不会自动创建这个目录?),在执行默认的SMSCMD命令。
2. LoadLeveler提交
SMSCMD设置为

llsubmit2脚本为

该脚本主要将作业号赋给SMSRID变量,便于之后使用llcancel命令取消作业。
SMSKILL变量设置为

llcancel2脚本为

目前我们使用Shell脚本作为SMS作业,Shell脚本可以直接运行,也可以在loadleveler中提交。同样Python脚本也可以在命令行直接运行,所以SMS应该支持Python脚本。

SMS作业脚本的简单说明

使用Python改写SMS作业脚本前,先简单说明下SMS中作业的提交机制。
SMS首先对作业脚本(.sms)进行预处理,生成任务文件(.job)。该步骤识别预处理宏语句(默认以%开头,可以自定义),并进行文本替换。例如引入头文件{shell}%include {/shell},将该语句用head.h文件的内容替换;变量替换{shell}%SMSNAME%{/shell},将该字符串替换为SMSNAME变量的值。
再根据SMSCMD设置的命令,运行任务文件。
任务通过RPC方式与SMS服务器交互。脚本调用{shell}smsinit{/shell},{shell}smscomplete{/shell},{shell}smsabort{/shell}等程序,通知服务器自身状态的变化。
通常,任务的基本流程相同,所以对以上程序的调用放在起始头文件head.h和结尾头文件tail.h中。系统开发时一般不需要考虑与SMS服务器交互的细节,直接使用包含头文件即可。
但因为需要用Python改写Shell脚本,原有的Shell头文件无法使用,必须将其转换为Python文件,所以得搞清除这两个头文件到底有什么用。

SMS作业头文件

请参考ecFlow的官网:《Understanding Includes

通用的head.h

脚本做了三项工作:

  1. 为与服务器的通信准备环境变量
    设置RPC需要的各项环境变量。
  2. 初始化任务
    调用smsinit通知sms服务器任务开始执行,并设置SMSRID。直接运行的任务使用pid号,LoadLeveler提交则用LoadLeveler作业号。
  3. 设置信号捕获
    当脚本非正常结束时,执行函数ERROR,调用smsabort通知服务器任务运行中止。
    通用的tail.h

脚本主要执行一项工作:
调用smscomplete通知服务器任务运行结束。
Python版的头文件也需要实现上述功能。

Python版简单头文件

参考SMS升级版——ecFlow——官网上的两篇文章
ecFlow@ECMWF
该文章使用子程序调用方式与服务器通信。
Native Python Tasks
该文章利用ecFlow的Python扩展与服务器的通信。

说明

与服务器通讯
SMS中只能选择第一篇文章的方法,通过{python}os.system{/python}调用子程序。
宏标识
另外,SMS预处理器的宏字符为{shell}%{/shell},而Python中{shell}%{/shell}是操作符,所以需要重新设置宏字符。第二篇文章使用{shell}${/shell}作为宏字符。
提交命令
尽管Python脚本可以在命令行直接运行,但SMS中无法使用默认SMSCMD设置提交作业,需要修改SMSCMD为

header.py

环境设置
使用{python}os.environ{/python}设置环境变量
信号捕捉
使用{python}signal.signal{/python}设置信号捕捉。
使用atexit模块设置程序退出时调用的参数。
初始化任务
使用{python}os.system{/python}调用{shell}smsinit{/shell}初始化任务。

tail.py

结束任务
使用{python}os.system{/python}调用{shell}smscomplete{/shell}结束任务。

task定义

用作测试的task定义

Python任务脚本

测试脚本test1.sms

测试结果

任务运行成功,XCDP中显示如下结果:

更进一步:使用LoadLeveler提交SMS作业

业务任务都由LoadLeveler提交,上面的任务定义和头文件仅考虑直接运行的情况,下面加上针对LoadLeveler的特殊处理。

任务文件

使用llsubmit2提交任务,使用llcancel2中止任务。

头文件(节选)

添加判断是否是LoadLeveler作业并设置SMSRID。

由LOADL_JOB_NAME判断是否是LoadLeveler作业,如果是,则用作业号启动,否则使用进程号。

任务脚本(节选)

在开头加上LoadLeveler作业脚本即可。

测试结果

可以提交作业,也可以中止作业。

总结

SMS完全支持Python脚本,可以使用Python脚本代替Shell脚本(如果真有这个必要的话)。