我怎样才能让qstat
给我完整的职位名称?
我知道qstat -r
提供了关于任务的详细信息,但是它太多了,并且包含了资源需求。
qstat -r
输出如下所示:
131806 0.25001 tumor_foca ajalali qw 09/29/2014 15:49:41 1 2-100:1 Full jobname: tumor_focality-TCGA-THCA-ratboost_linear_svc Hard Resources: distribution=wheezy (0.000000) h_rt=72000 (0.000000) mem_free=15G (0.000000) h_vmem=15G (0.000000) h_stack=256M (0.000000) Soft Resources: 131807 0.25001 vital_stat ajalali qw 09/29/2014 15:49:41 1 2-100:1 Full jobname: vital_status-TCGA-LGG-ratboost_linear_svc Hard Resources: distribution=wheezy (0.000000) h_rt=72000 (0.000000) mem_free=15G (0.000000) h_vmem=15G (0.000000) h_stack=256M (0.000000) Soft Resources:
现在我唯一的select是grep
的输出,因为我需要:
$ qstat -r | grep "Full jobname" -B1 -- 131806 0.25001 tumor_foca ajalali qw 09/29/2014 15:49:41 1 2-100:1 Full jobname: tumor_focality-TCGA-THCA-ratboost_linear_svc -- 131807 0.25001 vital_stat ajalali qw 09/29/2014 15:49:41 1 2-100:1 Full jobname: vital_status-TCGA-LGG-ratboost_linear_svc
我能更好地做出更好的输出吗?
这个有点混乱,但是它在命令历史中是一个简单的解决方案。 所有的标准工具。 输出与你从普通的qstat调用中获得的结果几乎相同,但你不会得到标题:
一内胆:
qstat -xml | tr '\n' ' ' | sed 's#<job_list[^>]*>#\n#g' \ | sed 's#<[^>]*>##g' | grep " " | column -t
命令描述:
将作业列为XML:
qstat -xml
删除所有换行符:
tr '\n' ' '
在列表中的每个工作条目之前添加换行符:
sed 's#<job_list[^>]*>#\n#g'
删除所有XML的东西:
sed 's#<[^>]*>##g'
在最后添加换行符的Hack:
grep " "
Columnize:
column -t
输出示例
351996 0.50502 ProjectA_XXXXXXXXX_XXXX_XXXXXX user123 r 2015-06-25T15:38:41 xxxxx-sim01@xxxxxx02.xxxxx.xxx 1 351997 0.50502 ProjectA_XXX_XXXX_XXX user123 r 2015-06-25T15:39:26 xxxxx-sim01@xxxxxx23.xxxxx.xxx 1 351998 0.50502 ProjectA_XXXXXXXXXXXXX_XXXX_XXXX user123 r 2015-06-25T15:40:26 xxxxx-sim01@xxxxxx14.xxxxx.xxx 1 351999 0.50502 ProjectA_XXXXXXXXXXXXXXXXX_XXXX_XXXX user123 r 2015-06-25T15:42:11 xxxxx-sim01@xxxxxx19.xxxxx.xxx 1 352001 0.50502 ProjectA_XXXXXXXXXXXXXXXXXXXXXXX_XXXX_XXXX user123 r 2015-06-25T15:42:11 xxxxx-sim01@xxxxxx11.xxxxx.xxx 1 352008 0.50501 runXXXX69 usr1 r 2015-06-25T15:49:04 xxxxx-sim01@xxxxxx17.xxxxx.xxx 1 352009 0.50501 runXXXX70 usr1 r 2015-06-25T15:49:04 xxxxx-sim01@xxxxxx01.xxxxx.xxx 1 352010 0.50501 runXXXX71 usr1 r 2015-06-25T15:49:04 xxxxx-sim01@xxxxxx06.xxxxx.xxx 1 352011 0.50501 runXXXX72 usr1 r 2015-06-25T15:49:04 xxxxx-sim01@xxxxxx21.xxxxx.xxx 1 352012 0.50501 runXXXX73 usr1 r 2015-06-25T15:49:04 xxxxx-sim01@xxxxxx13.xxxxx.xxx 1 352013 0.50501 runXXXX74 usr1 r 2015-06-25T15:49:04 xxxxx-sim01@xxxxxx11.xxxxx.xxx 1
这个脚本工作得很好。 它看起来像是来自剑桥。 http://www.hep.ph.ic.ac.uk/~dbauer/grid/myqstat.py
对于Python 3:
#!/usr/bin/python import xml.dom.minidom import os import sys import string f=os.popen('qstat -u \* -xml -r') dom=xml.dom.minidom.parse(f) jobs=dom.getElementsByTagName('job_info') run=jobs[0] runjobs=run.getElementsByTagName('job_list') def fakeqstat(joblist): for r in joblist: try: jobname=r.getElementsByTagName('JB_name')[0].childNodes[0].data jobown=r.getElementsByTagName('JB_owner')[0].childNodes[0].data jobstate=r.getElementsByTagName('state')[0].childNodes[0].data jobnum=r.getElementsByTagName('JB_job_number')[0].childNodes[0].data jobtime='not set' if(jobstate=='r'): jobtime=r.getElementsByTagName('JAT_start_time')[0].childNodes[0].data elif(jobstate=='dt'): jobtime=r.getElementsByTagName('JAT_start_time')[0].childNodes[0].data else: jobtime=r.getElementsByTagName('JB_submission_time')[0].childNodes[0].data print(jobnum, '\t', jobown.ljust(16), '\t', jobname.ljust(16),'\t', jobstate,'\t',jobtime) except Exception as e: print(e) fakeqstat(runjobs)
对于Python 2:
#!/usr/bin/python import xml.dom.minidom import os import sys import string #import re f=os.popen('qstat -u \* -xml -r') dom=xml.dom.minidom.parse(f) jobs=dom.getElementsByTagName('job_info') run=jobs[0] runjobs=run.getElementsByTagName('job_list') def fakeqstat(joblist): for r in joblist: jobname=r.getElementsByTagName('JB_name')[0].childNodes[0].data jobown=r.getElementsByTagName('JB_owner')[0].childNodes[0].data jobstate=r.getElementsByTagName('state')[0].childNodes[0].data jobnum=r.getElementsByTagName('JB_job_number')[0].childNodes[0].data jobtime='not set' if(jobstate=='r'): jobtime=r.getElementsByTagName('JAT_start_time')[0].childNodes[0].data elif(jobstate=='dt'): jobtime=r.getElementsByTagName('JAT_start_time')[0].childNodes[0].data else: jobtime=r.getElementsByTagName('JB_submission_time')[0].childNodes[0].data print jobnum, '\t', jobown.ljust(16), '\t', jobname.ljust(16),'\t', jobstate,'\t',jobtime fakeqstat(runjobs)
我目前正在写我自己的qstat
包装,以获得一个干净,有用的和可定制的输出。
这是github存储库 。 该项目已经增长太多,代码被粘贴在这个消息。
它附带一个安装程序,并且应该可以在Python 2.7和3(没有任何问题)的情况下工作(如果需要,安装脚本会进行修改)。 qjobs -h
为可用选项提供了一些帮助。 在接下来的几天中,我将在github wiki上撰写更完整的文档。
我会尽可能地更新这个信息,以坚持目前的项目状态。 请随意在这里(或在github上)发表评论以征求功能/报告问题。
在不久的将来,我将尝试添加一个完全交互式的模式来更轻松地浏览工作列表。 当然,经典的文本输出仍然可用(可能对发送输出或快速检查未完成/正在运行的作业有用)。
命令qjobs
给出:
5599109 short_name r 2015-06-25 10:27:39 queue1 5599110 jobName r 2015-06-25 10:35:39 queue2 5599111 a_long_job_name qw 2015-06-25 10:40:39 5599112 foo qw 2015-06-25 10:40:39 5599113 bar qw 2015-06-25 10:40:39 5599114 baz qw 2015-06-25 10:40:39 5599115 beer qw 2015-06-25 10:40:39 tot: 7 r: 2 qw: 5
命令qjobs -o
给出:
tot: 7 r: 2 qw: 5
命令qjobs -o inek -t
给出( e
是从开始/子时间开始经过的时间,格式可以使用Python的格式规范Mini-Language来定制; k
是带有域的完整队列名称):
5598985 SpongeBob 522:02 (21.75 days) queue1@node23.domain.fake 5598987 ping_java 521:47 (21.74 days) queue1@node39.domain.fake 5598988 run3.14 521:46 (21.74 days) queue2@node40.domain.fake 5598990 strange_job_42 521:42 (21.74 days) queue3@node36.domain.fake 5598991 coffee-maker 521:39 (21.74 days) queue2@node34.domain.fake 5598992 dumbtask 521:29 (21.73 days) queue1@node14.domain.fake
qjobs -i
给出了可用“项目”的完整列表。 每个这个项目是可利用的:
-o ITEMS
); -t
(例如,如在前两个例子中,按照状态来计数)。 -s
排序作业的标准,默认为-s ips
这意味着作业列表按ID排序,然后按优先级排序,最后按打印之前的状态排序。 qjobs -i
的结果是:
i: job id p: job priority n: job name o: job owner s: job state t: job start/submission time e: elapsed time since start/submission q: queue name without domain d: queue domain k: queue name with domain r: requested queue(s) l: number of slots used
对于我来说,物理化学家的脚本没有工作,所以我写了一个非常简单的脚本使用xml.tree.ElementTree模块,我认为比xml.dom.minidom
import os import xml.etree.ElementTree as ET f = os.popen('qstat -x') tree = ET.parse(f) root = tree.getroot() print "Job_Id walltime state nodes Job_Name" print "------ -------- ----- --------------- --------------------------" for job in root: print job.find('Job_Id').text, " ", print job.find('resources_used').find('walltime').text, " ", print job.find('job_state').text, " ", print job.find('Resource_List').find('nodes').text, " ", print job.find('Job_Name').text
感谢JLT提供简单的代码。 我扩大了一点,以适应我的需求,使它看起来不错。
示例输出:
Job ID Job Name Owner Status ------ ------------------------------------ ------ ------ 201716 AtacSilN100400K mtsige R 201771 IsoOnGrap400K mtsige R 202067 AtacOnSilica400K mtsige R 202100 AtacGrapN100400K mtsige R 202135 AtacOnSilc400K mtsige R 202145 AtacOnGrap400K mtsige R 202152 AtacOnGraphN3360K mtsige R 202161 AtacticSilicaN10 mtsige R 202163 AtacGrapN10 mtsige R 202169 AtacSilcN10 mtsige R 202192 wallpmma07 am110 R 202193 wallpmma03 am110 R 202194 att03wpm_95solps am110 R 202202 AtacticSilicaN3 mtsige R 203260 8test18_trop_2p ico R 203359 parseAll_Bob/Sub951By50/Cyl20A_atom1 oge1 R 203360 parseAll_Bob/Sub951By50/Cyl30A_atom1 oge1 R 203361 parseAll_Bob/Sub951By50/Cyl30A_atom2 oge1 R
码:
#!/opt/bin/python3 import os import xml.etree.ElementTree as ET #Fields fields=['Job_Id','Job_Name','Job_Owner','job_state'] names=['Job ID','Job Name','Owner','Status'] #Get job info f = os.popen('qstat -x') tree = ET.parse(f) root = tree.getroot() n_fields=len(fields) jobs=[[job.find(field).text for field in fields] for job in root] max_lengths=[len(name) for name in names] sep=' ' #Identify max characer length per field for j in jobs: for i in range(n_fields): #Chop off anything after and including '@' or '.' from all fields if j[i].find('@')>0: j[i]=j[i][:j[i].find('@')] if j[i].find('.')>0: j[i]=j[i][:j[i].find('.')] if(len(j[i])>max_lengths[i]): max_lengths[i]=len(j[i]) #Field names for i in range(n_fields): print('{s:^{length}}'.format(s=names[i],length=max_lengths[i]),end=sep) print() #Dashes for i in range(n_fields): print('-'*max_lengths[i],end=sep) print() #Jobs for j in jobs: for i in range(n_fields): if j[i].find('@')>0: j[i]=j[i][:j[i].find('@')] print('{s:<{length}}'.format(s=j[i],length=max_lengths[i]),end=sep) print()
一个可怜的KISS解决方案:
qstat -xml -f -u \* | fgrep JB_name | wc -l