Formater la sortie de cputime pour ps

13

J'essaie d'écrire un script qui peut surveiller l'utilisation du processeur d'un processus sur un intervalle (pour créer un graphique).

Jusqu'à présent, c'est la commande que j'utilise

ps -p $PROCID -o cputime,etimes

Ma seule préoccupation est que la sortie de cputime semble être [dd]hh:mm(ou quelque chose de similaire, je ne me souviens plus du haut de ma tête maintenant)

Existe-t-il un moyen de formater cputime en secondes, un peu comme etime -> etimes pour obtenir le temps écoulé en secondes?

Edit: c'est la sortie que je reçois actuellement

2-03:01:33 2653793

J'aimerais que le premier paramètre soit formaté en secondes, pas en jours-heures: minutes: secondes.

dreadiscool
la source
pouvez-vous s'il vous plaît ajouter la sortie que vous recevez maintenant et la sortie que vous souhaitez recevoir?
Simply_Me
@Simply_Me J'ai modifié l'article
dreadiscool
@ John1024 Oui, c'est le nombre de jours.
dreadiscool

Réponses:

9

Cela convertit la première fois en secondes:

ps -p $PROCID -o cputime,etimes | awk -F'[: ]+' '/:/ {t=$3+60*($2+60*$1); print t,$NF}'

Par exemple, la commande ps produit:

$ ps -p 5403 -o cputime,etimes
    TIME ELAPSED
01:33:38 1128931

La awkcommande traite cela et retourne:

ps -p 5403 -o cputime,etimes | awk -F'[: ]+' '/:/ {t=$3+60*($2+60*$1); print t,$NF}'
5618 1128931

Explication

  • -F'[: ]+'

    Cela indique à awk de traiter les deux-points et les espaces comme des séparateurs de champs. De cette façon, les heures, les minutes et les secondes apparaissent comme des champs séparés.

  • /:/ {t=$3+60*($2+60*$1); print t,$NF}

    L'initiale /:/restreint le code à travailler uniquement sur les lignes qui incluent deux points. Cela supprime les lignes d'en-tête. Le nombre de secondes est calculé à partir des heures, minutes, secondes via t=$3+60*($2+60*$1). La valeur résultante pour test ensuite imprimée parallèlement au temps écoulé.

Jours de manutention

Si psproduit des jours, des heures, des minutes, des secondes, comme dans:

2-03:01:33

Utilisez ensuite ce code à la place:

ps -p $PROCID -o cputime,etimes | awk -F'[-: ]+' '/:/ {t=$4+60*($3+60*($2+24*$1)); print t,$NF}'

Si des jours peuvent ou non être ajoutés à la sortie, utilisez cette commande de combinaison:

ps -p $PROCID -o cputime,etimes | awk -F'[-: ]+' '/:/ && NF==5 { t=$4+60*($3+60*($2+24*$1)); print t,$NF} /:/ && NF==4 {t=$3+60*($2+60*$1); print t,$NF}'
John1024
la source
Pardonnez-moi si je me trompe, mais il ne semble pas que cette commande prenne en compte les jours, qui peuvent également être
ajoutés
C'est vrai: mon système n'affichait de jours pour aucun processus. Je peux deviner à quoi pourraient ressembler des jours, mais pouvez-vous donner un exemple concret?
John1024
2-03: 01: 33 est de 2 jours, 3 heures, 1 minute et 33 secondes. Cependant, les jours ne sont pas toujours ajoutés. Sur mon système, il n'est ajouté que si le processus est actif depuis plus de 24 heures. Merci pour votre aide jusqu'ici btw, je l'apprécie
dreadiscool
@ user1772510 Réponse mise à jour pour gérer les jours.
John1024
Merci pour toute votre aide, si je pouvais voter, je voterais aussi (pas assez de représentants dans cette communauté), je l'apprécie profondément!
dreadiscool
2

Si vous ne voulez pas apporter awk dans le jeu, une solution bash pure (t_str contient la chaîne formatée, t_sec le temps décodé en secondes):

# Decode the CPU time format [dd-]hh:mm:ss.
IFS="-:" read c1 c2 c3 c4 <<< "$t_str"
if [ -n "$c4" ]
then
  t_sec=$((10#$c4+60*(10#$c3+60*(10#$c2+24*10#$c1))))
else
  t_sec=$((10#$c3+60*(10#$c2+60*10#$c1)))
fi
Nicolas Breton
la source
0

Vous ne spécifiez pas pour quel système d'exploitation il s'agit; s'il s'agit de Linux, et étant donné que vous êtes intéressé par la surveillance d'un processus spécifique, vous pourriez trouver plus intéressant d'analyser /proc/$PROCID/stat- voir la proc(5)page de manuel pour plus de détails.

Toby Speight
la source