Réponses:
Existe-t-il un moyen de sortie
lstart
au format ISO commeYYYY-MM-DD HH:MM:SS
?
Avec awk
+ date
coopération:
ps -eo lstart,pid,cmd --sort=start_time | awk '{
cmd="date -d\""$1 FS $2 FS $3 FS $4 FS $5"\" +\047%Y-%m-%d %H:%M:%S\047";
cmd | getline d; close(cmd); $1=$2=$3=$4=$5=""; printf "%s\n",d$0 }'
Approche alternative à l'aide du mot clé ps etimes
(temps écoulé depuis le démarrage du processus, en secondes):
ps -eo etimes,pid,cmd --sort=etimes | awk '{
cmd="date -d -"$1"seconds +\047%Y-%m-%d %H:%M:%S\047";
cmd | getline d; close(cmd); $1=""; printf "%s\n",d$0 }'
date -d -"$1"seconds
- différence entre l'horodatage actuel et l' elapsed
heure, donnera la valeur d' horodatage du processusetimes
au lieu de lstart
vous obtenez le temps écoulé en secondes, ce qui est un peu plus facile à passer date -d -999seconds
.
Vous pouvez trier avec:
ps -eo lstart,pid,cmd --sort=start_time
Notez que ce lstart
n'est pas l'une des ps
colonnes Unix standard .
Tous les systèmes n'en ont pas et la sortie varie entre les implémentations et potentiellement entre les paramètres régionaux.
Par exemple, sur FreeBSD ou avec le ps
from procps-ng
(comme on le trouve généralement sur les systèmes Linux non intégrés) et les C
paramètres régionaux, vous obtiendrez:
Wed Nov 1 12:36:15 2017
Sur macOS:
Wed 1 Nov 12:36:15 2017
De plus, comme il ne vous donne pas le décalage GMT, la sortie est ambiguë dans les fuseaux horaires qui implémentent l'heure d'été (où il y a une heure dans l'année où les mêmes dates se produisent deux fois) et ne trient pas toujours chronologiquement.
Ici, vous pouvez forcer les heures à être UTC et utiliser perl
le Date::Manip
module de pour analyser la date d'une manière qui comprend différents formats naturels:
(export TZ=UTC0 LC_ALL=C
ps -A -o lstart= -o pid= -o args= |
perl -MDate::Manip -lpe '
s/^(\s*\S+){5}/UnixDate(ParseDate($&), "%Y-%m-%dT%T+00:00")/e' |
sort
)
Ou avec ksh93
lequel reconnaît également ces formats de date:
(export TZ=UTC0 LC_ALL=C
unset -v IFS
ps -A -o lstart= -o pid= -o args= |
while read -r a b c d e rest; do
printf '%(%FT%T+00:00)T %s\n' "$a $b $c $d $e" "$rest"
done
)
(attention, il supprime les blancs de fin de chaque ligne)
Ou avec zsh
et GNU date
:
(export LC_ALL=C TZ=UTC0
(){
paste -d '\0' <(cut -c1-24 < $1 | date -f- --iso-8601=s) \
<(cut -c25- < $1) | sort
} =(ps -A -o lstart= -o pid= -o args=)
)
Ou avec bash
(ou zsh
) sur Linux uniquement et avec GNU date
:
(export LC_ALL=C TZ=UTC0
{
paste -d '\0' <(cut -c1-24 | date -f- --iso-8601=s) \
<(cut -c25- < /dev/stdin) | sort
} <<< "$(ps -A -o lstart= -o pid= -o args=)"
)
Sachez également que l'heure de début du processus n'est pas nécessairement la même que la dernière fois que le processus a exécuté une commande car les processus peuvent généralement exécuter plus d'une commande au cours de leur vie (ceux qui ne le sont généralement pas ceux qui n'exécutent jamais une commande) . En d'autres termes, cela ne correspond pas nécessairement au moment où la commande ( args
champ, l'équivalent standard de cmd
) a été lancée.
$ sh -c 'sleep 4; exec sleep 123' & sleep 234 & sleep 5
[1] 9380
[2] 9381
$ (export TZ=UTC0 LC_ALL=C; ps -o lstart,pid,args | perl -MDate::Manip -lpe 's/^(\s*\S+){5}/UnixDate(ParseDate($&), "%Y-%m-%dT%T+00:00")/e')
2017-10-30T17:21:06+00:00 3071 zsh
2017-11-01T15:47:48+00:00 9380 sleep 123
2017-11-01T15:47:48+00:00 9381 sleep 234
Voyez comment sleep 123
est considéré comme démarré en même temps que sleep 234
même s'il a été démarré 4 secondes plus tard. C'est parce que ce processus 9388 était initialement en cours d'exécution sh
(et attendait 4 secondes sleep 4
) avant d'être exécuté sleep 123
(et avant cela, il exécutait du zsh
code tel qu'il était bifurqué par mon shell interactif, donc à différents moments, pour ce processus, vous auriez vu dans la ps
sortie:, zsh
alors sh
, alors sleep
).
Voici une implémentation avec des performances plus élevées (n'a pas besoin d'exécuter un nouveau processus par ligne):
ps -eo etimes,pid,args --sort=etimes | awk 'BEGIN{now=systime()} {$1=strftime("%Y-%m-%d %H:%M:%S", now-$1); print $0}'
et cela permet aussi de changer assez facilement l'ordre des colonnes. Par exemple, la pid
première et l'heure de début dans la deuxième colonne:
ps -eo pid,etimes,args --sort=etimes | awk 'BEGIN{now=systime()} {$2=strftime("%Y-%m-%d %H:%M:%S", now-$2); print $0}'
lstart
un tel format bizarre. C'est proche de RFC 2822 mais avec l'année à la fin.