Qstat и длинные имена работ
Как я могу получить 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:
Прямо сейчас мой единственный вариант - 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
Могу ли я сделать это лучше, чтобы получить более приятный результат?
Ответы
Ответ 1
Это немного грязно, но оно работает как простое решение для истории команд. Все стандартные инструменты. Вывод практически такой же, как и у обычного 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'
Взломайте новую строку в конце:
grep " "
Columnize:
column -t
Пример вывода
351996 0.50502 ProjectA_XXXXXXXXX_XXXX_XXXXXX user123 r 2015-06-25T15:38:41 [email protected] 1
351997 0.50502 ProjectA_XXX_XXXX_XXX user123 r 2015-06-25T15:39:26 [email protected] 1
351998 0.50502 ProjectA_XXXXXXXXXXXXX_XXXX_XXXX user123 r 2015-06-25T15:40:26 [email protected] 1
351999 0.50502 ProjectA_XXXXXXXXXXXXXXXXX_XXXX_XXXX user123 r 2015-06-25T15:42:11 [email protected] 1
352001 0.50502 ProjectA_XXXXXXXXXXXXXXXXXXXXXXX_XXXX_XXXX user123 r 2015-06-25T15:42:11 [email protected] 1
352008 0.50501 runXXXX69 usr1 r 2015-06-25T15:49:04 [email protected] 1
352009 0.50501 runXXXX70 usr1 r 2015-06-25T15:49:04 [email protected] 1
352010 0.50501 runXXXX71 usr1 r 2015-06-25T15:49:04 [email protected] 1
352011 0.50501 runXXXX72 usr1 r 2015-06-25T15:49:04 [email protected] 1
352012 0.50501 runXXXX73 usr1 r 2015-06-25T15:49:04 [email protected] 1
352013 0.50501 runXXXX74 usr1 r 2015-06-25T15:49:04 [email protected] 1
Ответ 2
Этот script работает очень хорошо. Похоже, это из Кембриджа. 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)
Ответ 3
Возможно, более простое решение: установите для SGE_LONG_JOB_NAMES значение -1, и qstat определит размер столбца имени:
export SGE_LONG_JOB_NAMES=-1
qstat -u username
Работает для меня.
Ура!
Ответ 4
В настоящее время я пишу свою собственную оболочку qstat
, чтобы получить чистый, полезный и настраиваемый вывод.
Вот репозиторий github. Проект вырос слишком сильно, чтобы код был вставлен в это сообщение.
Он поставляется с установщиком и должен работать без каких-либо проблем как с Python 2.7, так и с 3 (установка script вносит необходимые изменения). qjobs -h
предоставляет некоторую помощь по доступным параметрам. Я напишу более полную документацию в следующие дни в викторике github.
Я обновляю это сообщение как можно чаще, чтобы придерживаться текущего состояния проекта. Пожалуйста, не стесняйтесь комментировать здесь (или на 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
истекшее время с момента запуска/суб-времени, формат настраивается с помощью Формат Spec. Мини-язык из Python; k
- это полное имя очереди с доменом):
5598985 SpongeBob 522:02 (21.75 days) [email protected]
5598987 ping_java 521:47 (21.74 days) [email protected]
5598988 run3.14 521:46 (21.74 days) [email protected]
5598990 strange_job_42 521:42 (21.74 days) [email protected]
5598991 coffee-maker 521:39 (21.74 days) [email protected]
5598992 dumbtask 521:29 (21.73 days) [email protected]
qjobs -i
дает полный список доступных "элементов". Каждый из этих элементов доступен как:
- вывод столбца (с
-o ITEMS
);
- как критерий для подсчета задания и получения итогового результата с
-t
(например, -t s
для подсчета по состоянию, как в двух первых примерах);
- как критерий для сортировки задания с помощью
-s
, по умолчанию это -s ips
, что означает, что список заданий сортируется по идентификатору, затем по приоритету и, наконец, по состоянию перед печатью.
Результатом 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
Ответ 5
Благодаря 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()
Ответ 6
Для меня физик-химик script не работал, поэтому я написал очень простой script, используя 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
Ответ 7
Плохое решение KISS:
qstat -xml -f -u \* | fgrep JB_name | wc -l
Ответ 8
код Python
import xmltodict
import subprocess as sp
import pandas as pd
qstat_xml = sp.check_output(['qstat','--xml'], stderr=sp.STDOUT) # read xml
stat_dict = xmltodict.parse(qstat_xml) # convert to dict
job_list = stat_dict['Data']['Job'] # select job_list
job_df = pd.DataFrame(job_list) # convert to dataframe
print('columns', job_df.columns) # print available columns
column_list = ['Job_Id', 'Job_Name']
selection_df = job_df[column_list] # select columns
print(selection_df)