Подтвердить что ты не робот

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

Могу ли я сделать это лучше, чтобы получить более приятный результат?

4b9b3361

Ответ 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)