ฉันต้องการเรียงลำดับผลลัพธ์ตามlstart
(เริ่มต้นกระบวนการ):
ps -eo lstart,pid,cmd
มีวิธีส่งออก lstart ในรูปแบบ ISO เช่น YYYY-MM-DD HH: MM: SS หรือไม่
แต่การเรียงลำดับเพียงอย่างเดียวไม่สามารถแก้ไขได้ ฉันต้องการรูปแบบวันที่ ISO จริง ๆ
ฉันต้องการเรียงลำดับผลลัพธ์ตามlstart
(เริ่มต้นกระบวนการ):
ps -eo lstart,pid,cmd
มีวิธีส่งออก lstart ในรูปแบบ ISO เช่น YYYY-MM-DD HH: MM: SS หรือไม่
แต่การเรียงลำดับเพียงอย่างเดียวไม่สามารถแก้ไขได้ ฉันต้องการรูปแบบวันที่ ISO จริง ๆ
คำตอบ:
มีวิธีการส่งออก
lstart
ในรูปแบบ ISOYYYY-MM-DD HH:MM:SS
หรือไม่
ด้วยawk
+ date
ความร่วมมือ:
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 }'
แนวทางอื่น ๆ โดยใช้คำหลักps etimes
(เวลาที่ผ่านไปนับตั้งแต่กระบวนการเริ่มต้นเป็นวินาที):
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
- ความแตกต่างระหว่างการประทับเวลาปัจจุบันและelapsed
เวลาจะให้ค่าการประทับเวลาของกระบวนการetimes
แทนคุณจะได้รับเวลาที่ผ่านไปในไม่กี่วินาทีซึ่งเป็นบิตง่ายที่จะผ่านเข้าไปในlstart
date -d -999seconds
คุณสามารถจัดเรียงด้วย:
ps -eo lstart,pid,cmd --sort=start_time
โปรดทราบว่าlstart
ไม่ใช่หนึ่งในps
คอลัมน์Unix มาตรฐาน
ไม่ใช่ทุกระบบที่มีหนึ่งและเอาท์พุทที่แตกต่างกันระหว่างการใช้งานและอาจเกิดขึ้นระหว่างสถานที่
ตัวอย่างเช่นบน FreeBSD หรือps
จากprocps-ng
(ตามปกติจะพบได้บนระบบที่ไม่ได้ใช้ระบบ Linux) และC
โลแคลคุณจะได้รับ:
Wed Nov 1 12:36:15 2017
ใน macOS:
Wed 1 Nov 12:36:15 2017
นอกจากนี้เนื่องจากมันไม่ให้ออฟเซ็ต GMT คุณจึงมีความคลุมเครือในเขตเวลาที่ใช้ DST (ซึ่งมีหนึ่งชั่วโมงในระหว่างปีที่มีวันที่เดียวกันเกิดขึ้นสองครั้ง) และไม่เรียงลำดับตามลำดับเวลาเสมอ
ที่นี่คุณสามารถบังคับเท่าที่จะเป็น UTC และใช้perl
ของDate::Manip
โมดูลที่จะแยกวันในลักษณะที่มีความเข้าใจในรูปแบบธรรมชาติที่แตกต่างกัน:
(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
)
หรือksh93
รูปแบบวันที่ที่ยอมรับด้วย:
(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
)
(ระวังว่าจะตัดช่องว่างต่อท้ายจากแต่ละบรรทัด)
หรือด้วยzsh
และ 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=)
)
หรือด้วยbash
(หรือzsh
) บน Linux เท่านั้นและด้วย 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=)"
)
นอกจากนี้โปรดระวังว่าเวลาเริ่มต้นกระบวนการไม่จำเป็นต้องเหมือนกับครั้งสุดท้ายที่กระบวนการดำเนินการคำสั่งเนื่องจากกระบวนการโดยทั่วไปสามารถเรียกใช้มากกว่าหนึ่งคำสั่งได้ตลอดอายุการใช้งาน . กล่าวอีกนัยหนึ่งมันไม่จำเป็นต้องสอดคล้องกับเวลาที่คำสั่ง ( args
ฟิลด์มาตรฐานเทียบเท่า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
ดูว่าsleep 123
มีการเริ่มต้นอย่างไรในเวลาเดียวกันsleep 234
แม้ว่าจะเริ่มขึ้น 4 วินาทีในภายหลัง นั่นเป็นเพราะกระบวนการ 9388 เริ่มต้นทำงานsh
(และรอ 4 วินาทีsleep 4
) ก่อนที่จะดำเนินการsleep 123
(และก่อนหน้านั้นมันกำลังรันzsh
โค้ดเนื่องจากมันถูกใช้งานโดยเชลล์เชิงโต้ตอบของฉันดังนั้นในเวลาที่แตกต่างกันสำหรับกระบวนการนั้นคุณจะต้อง เห็นได้ในps
ผลลัพธ์: zsh
จากsh
นั้นจากนั้นsleep
)
นี่คือการใช้งานที่มีประสิทธิภาพสูงกว่า (ไม่จำเป็นต้องดำเนินการกระบวนการใหม่ต่อบรรทัด):
ps -eo etimes,pid,args --sort=etimes | awk 'BEGIN{now=systime()} {$1=strftime("%Y-%m-%d %H:%M:%S", now-$1); print $0}'
และสิ่งนี้ทำให้เปลี่ยนการเรียงลำดับคอลัมน์ได้ง่ายเช่นกัน ตัวอย่างเช่นpid
ครั้งแรกและเวลาเริ่มต้นเป็นคอลัมน์ที่สอง:
ps -eo pid,etimes,args --sort=etimes | awk 'BEGIN{now=systime()} {$2=strftime("%Y-%m-%d %H:%M:%S", now-$2); print $0}'
lstart
มีรูปแบบที่แปลกประหลาด มันใกล้กับ RFC 2822 แต่เมื่อเทียบกับปีที่แล้ว