Réponses:
Existe-t-il un moyen de sortie
lstartau format ISO commeYYYY-MM-DD HH:MM:SS?
Avec awk+ datecoopé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' elapsedheure, donnera la valeur d' horodatage du processusetimesau lieu de lstartvous 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 lstartn'est pas l'une des pscolonnes 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 psfrom procps-ng(comme on le trouve généralement sur les systèmes Linux non intégrés) et les Cparamè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 perlle Date::Manipmodule 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 ksh93lequel 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 zshet 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 ( argschamp, 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 123est considéré comme démarré en même temps que sleep 234mê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 zshcode tel qu'il était bifurqué par mon shell interactif, donc à différents moments, pour ce processus, vous auriez vu dans la pssortie:, zshalors 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 pidpremiè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}'
lstartun tel format bizarre. C'est proche de RFC 2822 mais avec l'année à la fin.