Jawaban:
Apakah ada cara untuk menghasilkan
lstart
dalam format ISO sepertiYYYY-MM-DD HH:MM:SS
?
Dengan awk
+ date
kerja sama:
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 }'
Pendekatan alternatif menggunakan kata kunci ps etimes
(waktu yang berlalu sejak proses dimulai, dalam detik):
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
- perbedaan antara cap waktu saat ini dan elapsed
waktu, akan memberikan nilai cap waktu prosesetimes
alih-alih lstart
Anda mendapatkan waktu yang berlalu dalam detik yang sedikit lebih mudah untuk dilewatkan date -d -999seconds
.
Anda dapat mengurutkan dengan:
ps -eo lstart,pid,cmd --sort=start_time
Perhatikan bahwa lstart
itu bukan salah satu dari ps
kolom Unix standar .
Tidak semua sistem memiliki satu, dan output bervariasi antara implementasi dan berpotensi antar lokal.
Misalnya, di FreeBSD atau dengan ps
dari procps-ng
(seperti yang biasanya ditemukan pada sistem berbasis Linux yang tidak tertanam) dan C
lokal, Anda akan mendapatkan:
Wed Nov 1 12:36:15 2017
Di MacOS:
Wed 1 Nov 12:36:15 2017
Juga, karena tidak memberi Anda offset GMT, outputnya ambigu dalam zona waktu yang menerapkan DST (di mana ada satu jam selama tahun di mana tanggal yang sama terjadi dua kali) dan tidak selalu menyortir secara kronologis.
Di sini, Anda bisa memaksa kali menjadi UTC dan menggunakan perl
's Date::Manip
modul untuk mengurai tanggal dengan cara yang mengerti format alam yang berbeda:
(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
)
Atau ksh93
yang juga mengenali format tanggal tersebut:
(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
)
(hati-hati, strip kosong kosong dari setiap baris)
Atau dengan zsh
dan 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=)
)
Atau dengan bash
(atau zsh
) hanya di Linux dan dengan 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=)"
)
Berhati-hatilah juga bahwa waktu mulai proses tidak harus sama dengan waktu terakhir proses mengeksekusi suatu perintah karena proses secara umum dapat menjalankan lebih dari satu perintah dalam masa hidup mereka (yang biasanya bukan yang tidak pernah menjalankan perintah) . Dengan kata lain, itu tidak selalu sesuai dengan waktu perintah ( args
bidang, standar yang setara dengan cmd
) dimulai.
$ 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
Lihat bagaimana sleep 123
ini dilihat sebagai telah dimulai pada saat yang sama sleep 234
meskipun itu dimulai 4 detik kemudian. Itu karena proses 9388 itu awalnya berjalan sh
(dan menunggu 4 detik sleep 4
) sebelum dieksekusi sleep 123
(dan sebelum itu, itu menjalankan zsh
kode seperti yang bercabang oleh shell interaktif saya, jadi pada titik waktu yang berbeda, untuk proses itu, Anda harus memiliki terlihat di ps
output:, zsh
lalu sh
, lalu sleep
).
Berikut ini adalah implementasi dengan kinerja yang lebih tinggi (tidak perlu menjalankan proses baru per baris):
ps -eo etimes,pid,args --sort=etimes | awk 'BEGIN{now=systime()} {$1=strftime("%Y-%m-%d %H:%M:%S", now-$1); print $0}'
dan ini memungkinkan cukup mudah untuk mengubah pemesanan kolom juga. Misalnya pid
pertama dan waktu mulai sebagai kolom kedua:
ps -eo pid,etimes,args --sort=etimes | awk 'BEGIN{now=systime()} {$2=strftime("%Y-%m-%d %H:%M:%S", now-$2); print $0}'
lstart
memiliki format yang aneh. Itu dekat dengan RFC 2822 tetapi dengan tahun pada akhirnya.