Respuestas:
¿Hay alguna forma de salida
lstart
en formato ISO comoYYYY-MM-DD HH:MM:SS
?
Con awk
+ date
cooperación:
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 }'
Enfoque alternativo utilizando la palabra clave ps etimes
(tiempo transcurrido desde que se inició el proceso, en segundos):
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
- diferencia entre la marca de elapsed
tiempo actual y la hora, dará el valor de marca de tiempo del procesoetimes
lugar de lstart
obtener el tiempo transcurrido en segundos, que es un poco más fácil de pasar date -d -999seconds
.
Puedes ordenar con:
ps -eo lstart,pid,cmd --sort=start_time
Tenga en cuenta que lstart
no es una de las ps
columnas estándar de Unix .
No todos los sistemas tienen uno, y la salida varía entre implementaciones y potencialmente entre entornos locales.
Por ejemplo, en FreeBSD o con ps
from procps-ng
(como se encuentra típicamente en sistemas basados en Linux no integrados) y la C
configuración regional, obtendrá:
Wed Nov 1 12:36:15 2017
En macOS:
Wed 1 Nov 12:36:15 2017
Además, dado que no le da el desplazamiento de GMT, la salida es ambigua en las zonas horarias que implementan DST (donde hay una hora durante el año donde ocurren las mismas fechas dos veces) y no siempre se clasifican cronológicamente.
Aquí, puede forzar que las horas sean UTC y usar perl
el Date::Manip
módulo para analizar la fecha de una manera que comprenda los diferentes formatos naturales:
(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
)
O con el ksh93
que también reconoce esos formatos de fecha:
(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
)
(tenga cuidado con que elimina los espacios en blanco finales de cada línea)
O con zsh
y 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=)
)
O con bash
(o zsh
) solo en Linux y con 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=)"
)
También tenga en cuenta que el tiempo de inicio del proceso no es necesariamente el mismo que la última vez que el proceso ejecutó un comando, ya que los procesos generalmente pueden ejecutar más de un comando en su vida (los que no son generalmente los que nunca ejecutan un comando) . En otras palabras, no necesariamente corresponde a la hora en que se inició el comando ( args
campo, el equivalente estándar de cmd
).
$ 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
Vea cómo sleep 123
se considera que se inició al mismo tiempo que sleep 234
aunque se inició 4 segundos después. Eso se debe a que ese proceso 9388 se estaba ejecutando inicialmente sh
(y esperando 4 segundos sleep 4
) antes de ejecutarse sleep 123
(y antes de eso, se estaba ejecutando el zsh
código tal como lo bifurcó mi shell interactivo, por lo que en diferentes momentos, para ese proceso, habría visto en la ps
salida:, zsh
entonces sh
, entonces sleep
).
Aquí hay una implementación con mayor rendimiento (no necesita ejecutar un nuevo proceso por línea):
ps -eo etimes,pid,args --sort=etimes | awk 'BEGIN{now=systime()} {$1=strftime("%Y-%m-%d %H:%M:%S", now-$1); print $0}'
y esto también permite cambiar fácilmente el orden de las columnas. Por ejemplo, pid
primero y hora de inicio como segunda columna:
ps -eo pid,etimes,args --sort=etimes | awk 'BEGIN{now=systime()} {$2=strftime("%Y-%m-%d %H:%M:%S", now-$2); print $0}'
lstart
tiene un formato tan extraño? Está cerca de RFC 2822 pero con año al final.