Comment puis-je obtenir qstat
de me donner des noms de poste complets?
Je sais que qstat -r
donne des informations détaillées sur la tâche, mais c’est trop et les ressources nécessaires sont incluses.
La sortie qstat -r
est comme:
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:
Pour le moment, ma seule option est de grep
la sortie comme il me faut:
$ 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
Puis-je le faire mieux pour avoir une meilleure sortie?
Ceci est un peu brouillon, mais cela fonctionne comme une solution simple à avoir dans l’historique des commandes. Tous les outils standard. La sortie est à peu près la même chose que ce que vous obtenez d'un appel qstat normal, mais vous n'obtiendrez pas les en-têtes:
Bon mot:
qstat -xml | tr '\n' ' ' | sed 's#<job_list[^>]*>#\n#g' \
| sed 's#<[^>]*>##g' | grep " " | column -t
Description des commandes:
Lister les travaux en XML:
qstat -xml
Supprimer toutes les nouvelles lignes:
tr '\n' ' '
Ajouter une nouvelle ligne avant chaque entrée de travail dans la liste:
sed 's#<job_list[^>]*>#\n#g'
Supprimer tout le contenu XML:
sed 's#<[^>]*>##g'
Hack pour ajouter une nouvelle ligne à la fin:
grep " "
Columnize:
column -t
Exemple de sortie
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
Ce script fonctionne plutôt bien. On dirait que ça vient de Cambridge. http://www.hep.ph.ic.ac.uk/~dbauer/grid/myqstat.py
Pour 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)
Pour 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)
Peut-être une solution plus simple: définissez SGE_LONG_JOB_NAMES sur -1 et qstat déterminera la taille de la colonne du nom:
export SGE_LONG_JOB_NAMES=-1
qstat -u username
Travaille pour moi.
À votre santé!
J'écris actuellement mon propre wrapper qstat
afin d'obtenir une sortie propre, utile et personnalisable.
Voici le répertoire github . Le projet a trop évolué pour que le code soit collé dans ce message.
Il est fourni avec un programme d’installation et devrait fonctionner sans problème avec Python 2.7 et 3 (le script d’installation apporte les modifications nécessaires). qjobs -h
fournit de l'aide sur les options disponibles. J'écrirai une documentation plus complète dans les prochains jours sur le wiki de github.
Je mettrai à jour ce message aussi souvent que possible pour coller à l'état actuel du projet. N'hésitez pas à commenter ici (ou sur github) pour demander des fonctionnalités/signaler des problèmes.
Dans un proche avenir, j'essaierai d'ajouter un mode entièrement interactif pour parcourir plus facilement la liste des tâches. Bien entendu, la sortie texte classique sera toujours disponible (il peut être utile d'envoyer la sortie par courrier électronique ou de vérifier rapidement les tâches en attente/en cours d'exécution).
La commande qjobs
donne:
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
La commande qjobs -o
donne:
tot: 7
r: 2 qw: 5
La commande qjobs -o inek -t
donne (e
est le temps écoulé depuis le début/la sous-heure, le format est personnalisable à l'aide de Spécification de format. Mini-langage de Python; k
est le nom complet de la file d'attente, avec le domaine):
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
donne une liste complète des 'articles' disponibles. Chacun de cet article est disponible en tant que:
-o ITEMS
);-t
(par exemple -t s
pour compter par état comme dans les deux premiers exemples);-s
, la valeur par défaut est -s ips
, ce qui signifie que la liste des travaux est triée par ID, puis par priorité et enfin par état avant d'être imprimée.Le résultat de qjobs -i
est:
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
Merci à JLT pour le code simple et agréable. Je l'ai un peu élargi pour répondre à mes besoins et lui donner une apparence agréable.
Exemple de sortie:
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
Code:
#!/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()
Pour moi, le script de Physical Chemist n'a pas fonctionné, j'ai donc écrit un script très simple en utilisant le module xml.tree.ElementTree que je considère comme un peu plus simple que 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
Une mauvaise solution KISS:
qstat -xml -f -u \* | fgrep JB_name | wc -l