web-dev-qa-db-fra.com

qstat et noms de travail longs

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?

30
adrin

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
30
mabahj

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)
7
PhysicalChemist

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é!

4
Andrey Kuehlkamp

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).

Exemple de sortie

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:

  • une sortie de colonne (avec -o ITEMS);
  • comme critère pour compter le travail et produire la sortie totale, avec -t (par exemple -t s pour compter par état comme dans les deux premiers exemples);
  • en tant que critère pour trier le travail avec -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
3
Adrien

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()
1
Oliver Evans

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
0
JLT

Une mauvaise solution KISS:

qstat -xml -f -u \* | fgrep JB_name | wc -l
0
ivspenna