Antworten:
Gibt es eine Möglichkeit, wie
lstart
im ISO-Format auszugebenYYYY-MM-DD HH:MM:SS
?
Mit awk
+ date
Kooperation:
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 }'
Alternativer Ansatz mit dem Schlüsselwort ps etimes
(verstrichene Zeit seit dem Start des Prozesses in Sekunden):
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
- Die Differenz zwischen dem aktuellen Zeitstempel und der elapsed
Zeit gibt den Zeitstempelwert des Prozesses anetimes
stattdessen das ps-Format verwenden, erhalten lstart
Sie die verstrichene Zeit in Sekunden, die etwas einfacher zu übermitteln ist date -d -999seconds
.
Sie können sortieren mit:
ps -eo lstart,pid,cmd --sort=start_time
Beachten Sie, dass dies lstart
keine der Standard-Unix- ps
Spalten ist.
Nicht alle Systeme verfügen über eines, und die Ausgabe variiert zwischen Implementierungen und möglicherweise zwischen Gebietsschemas.
Unter FreeBSD oder mit dem ps
from procps-ng
(wie es normalerweise bei nicht eingebetteten Linux-basierten Systemen der C
Fall ist) und dem Gebietsschema erhalten Sie Folgendes:
Wed Nov 1 12:36:15 2017
Unter macOS:
Wed 1 Nov 12:36:15 2017
Da der GMT-Offset nicht angezeigt wird, ist die Ausgabe in Zeitzonen, in denen die Sommerzeit implementiert ist (in denen es eine Stunde im Jahr gibt, in der dieselben Daten zweimal vorkommen), nicht eindeutig und nicht immer chronologisch sortiert.
Hier können Sie die UTC-Zeiten erzwingen und mithilfe perl
des Date::Manip
Moduls das Datum so analysieren, dass verschiedene natürliche Formate verstanden werden:
(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
)
Oder mit ksh93
denen auch diese Datumsformate erkannt werden:
(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
)
(Vorsicht, es werden nachgestellte Leerzeichen von jeder Zeile entfernt)
Oder mit zsh
und 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=)
)
Oder nur mit bash
(oder zsh
) unter Linux und mit 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=)"
)
Beachten Sie auch, dass die Prozessstartzeit nicht unbedingt mit der letzten Zeit übereinstimmt, zu der der Prozess einen Befehl ausgeführt hat, da Prozesse im Allgemeinen mehr als einen Befehl in ihrem Leben ausführen können (diejenigen, die dies nicht tun, sind im Allgemeinen diejenigen, die niemals einen Befehl ausführen). . Mit anderen Worten, es entspricht nicht unbedingt der Zeit, zu der der Befehl ( args
Feld, das Standardäquivalent von cmd
) gestartet wurde.
$ 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
Sehen Sie, wie sleep 123
es als gleichzeitig gestartet angesehen wird sleep 234
, obwohl es 4 Sekunden später gestartet wurde. Dies liegt daran, dass dieser 9388-Prozess ursprünglich ausgeführt wurde sh
(und 4 Sekunden darauf wartete sleep 4
), bevor er ausgeführt wurde sleep 123
(und zuvor zsh
Code ausgeführt wurde, wie er von meiner interaktiven Shell gespalten wurde , sodass Sie ihn zu unterschiedlichen Zeitpunkten für diesen Prozess hätten in der ps
Ausgabe gesehen: zsh
dann sh
, dann sleep
).
Hier ist eine Implementierung mit höherer Leistung (es muss kein neuer Prozess pro Zeile ausgeführt werden):
ps -eo etimes,pid,args --sort=etimes | awk 'BEGIN{now=systime()} {$1=strftime("%Y-%m-%d %H:%M:%S", now-$1); print $0}'
und dies ermöglicht es auch ziemlich einfach, die Spaltenreihenfolge zu ändern. Zum Beispiel pid
erste und Startzeit als zweite Spalte:
ps -eo pid,etimes,args --sort=etimes | awk 'BEGIN{now=systime()} {$2=strftime("%Y-%m-%d %H:%M:%S", now-$2); print $0}'
lstart
so ein komisches Format. Es liegt in der Nähe von RFC 2822, aber mit dem Jahr am Ende.