Bagaimana cara memeriksa berapa lama proses telah berjalan?

243

Saya ingin menghindari melakukan ini dengan meluncurkan proses dari aplikasi pemantauan.

tepang
sumber

Jawaban:

311

Di Linux dengan psdari procps(-ng)(dan sebagian besar sistem lain karena ini ditentukan oleh POSIX):

ps -o etime= -p "$$" 

Di mana $$PID dari proses yang ingin Anda periksa. Ini akan mengembalikan waktu yang telah berlalu dalam format [[dd-]hh:]mm:ss.

Menggunakan -o etimememberitahu psbahwa Anda hanya ingin bidang waktu yang telah berlalu, dan =pada akhir yang menekan header (tanpa, Anda mendapatkan garis yang mengatakan ELAPSEDdan kemudian waktu di baris berikutnya; dengan, Anda hanya mendapatkan satu baris dengan waktu) .

Atau, dengan versi yang lebih baru dari paket alat procps-ng (3.3.0 atau lebih tinggi) di Linux atau FreeBSD 9.0 atau lebih tinggi (dan mungkin yang lain), gunakan:

ps -o etimes= -p "$$"

(dengan tambahan s) untuk mendapatkan waktu yang diformat seperti detik, yang lebih berguna dalam skrip.

Di Linux, psprogram mendapatkan ini dari /proc/$$/stat, di mana salah satu bidang (lihat man proc) adalah waktu mulai proses. Sayangnya, ini ditentukan sebagai waktu dalam jiffies (penghitung waktu sewenang-wenang yang digunakan dalam kernel Linux) sejak sistem boot. Jadi Anda harus menentukan waktu di mana sistem boot (dari /proc/stat), jumlah jiffies per detik pada sistem ini, dan kemudian lakukan perhitungan untuk mendapatkan waktu yang telah berlalu dalam format yang berguna.

Ternyata menjadi sangat rumit untuk menemukan nilai HZ (yaitu, jiffies per detik). Dari komentar di sysinfo.cdalam paket procps, seseorang dapat A) memasukkan file header kernel dan mengkompilasi ulang jika kernel yang berbeda digunakan, B) menggunakan sysconf()fungsi posix , yang, sayangnya, menggunakan nilai kode-keras yang dikompilasi ke dalam perpustakaan C, atau C) bertanya pada kernel, tetapi tidak ada antarmuka resmi untuk melakukan itu. Jadi, pskode tersebut mencakup serangkaian kludges yang menentukan nilai yang benar. Wow.

Jadi nyaman untuk psmelakukan itu semua untuk Anda. :)

Sebagai catatan pengguna @ 336_, di Linux (ini bukan portabel), Anda dapat menggunakan statperintah untuk melihat tanggal akses, modifikasi, atau perubahan status untuk direktori /proc/$$(di mana lagi $$adalah proses yang menarik). Ketiga angka harus sama, jadi

stat -c%X /proc/$$

akan memberi Anda waktu proses itu $$dimulai, dalam detik sejak zaman. Itu masih tidak seperti yang Anda inginkan, karena Anda masih perlu melakukan matematika untuk mengurangi itu dari waktu saat ini untuk mendapatkan waktu yang telah berlalu - saya kira sesuatu seperti itu date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"akan berhasil, tetapi itu agak canggung. Satu keuntungan yang mungkin adalah bahwa jika Anda menggunakan output format panjang seperti -c%xalih - alih -c%X, Anda mendapatkan resolusi yang lebih besar daripada detik seluruh angka. Tetapi, jika Anda membutuhkannya, Anda mungkin harus menggunakan pendekatan audit proses karena waktu menjalankan perintah stat akan mengganggu keakuratan.

mattdm
sumber
1
Hai! Apakah etime=salah ketik? Saya hanya dapat menemukan etimedi halaman manual.
Kent Pawar
16
@KentPawar Ini bukan kesalahan ketik. Kosong =menekan tajuk. Cobalah tanpa, atau cobaps -p $$ -o etime="Silly Header Here"
mattdm
4
ps -p $ (pgrep find) -o etime =
mafrosis
1
Bagus. Saya lebih suka etimesdiri saya karena itu dapat dibaca mesin
Asfand Qazi
1
@alexmurray Itu hanya menelepon sysconf()dan karena itu memberi Anda nilai kode dari perpustakaan C, seperti yang disebutkan, bukan?
mattdm
36

Portabel:

% ps -o stime,time $$
STIME     TIME
Jan30 00:00:06

yaitu shell yang dimulai pada 30 Januari dan total sekitar 6 detik waktu CPU.

Mungkin ada cara yang lebih tepat atau lebih dapat diurai tetapi kurang portabel untuk mendapatkan informasi ini. Periksa dokumentasi psperintah Anda atau procsistem file Anda .

Di Linux, informasi ini tinggal di /proc/$pid/stat.

awk '{print "CPU time: " $14+$15; print "start time: " $22}' /proc/$$/stat

Waktu CPU dalam jiffies; Saya tidak tahu bagaimana menemukan nilai jiffy dari shell. Waktu mulai relatif terhadap waktu boot (ditemukan dalam /proc/uptime).

Gilles
sumber
3
Menemukan nilai HZ (yaitu, jiffies per detik) ternyata sangat rumit! Dari komentar di sysinfo.cdalam paket procps, seseorang dapat a) memasukkan file header kernel (dan mengkompilasi ulang jika kernel yang berbeda digunakan, b) menggunakan fungsi posix sysconf (), yang, sayangnya, menggunakan nilai kode yang dikompilasi ke dalam c library, atau c) meminta kernel, dan tidak ada antarmuka resmi untuk melakukan itu. Jadi, kode tersebut mencakup serangkaian kludges yang menentukan nilai yang benar. Wow.
mattdm
1
Halaman psmanual menyatakan bahwa time"waktu CPU kumulatif". Saya pikir apa yang dicari OP adalah etime, atau "waktu yang berlalu sejak proses dimulai". pubs.opengroup.org/onlinepubs/000095399/utilities/ps.html
rinogo
1
Lagipula tidak terlalu "portabel": "ps: stime: kata kunci tidak ditemukan" di FreeBSD. Setidaknya itu mendukung etime.
n.st
18
ps -eo pid,comm,cmd,start,etime | grep -i X

X adalah nama prosesnya

mezi
sumber
2
mungkin harus menambahkan grep -v grep.
Brian
ps -o pid,comm,cmd,start,etime -p Xuntuk melihat PID X.
codeforester
13

psmengambil -oopsi untuk menentukan format output, dan salah satu kolom yang tersedia adalah etime. Menurut halaman manual:

etime - waktu yang berlalu sejak proses dimulai, dalam bentuk [[dd-] jj:] mm: dd.

Dengan demikian Anda dapat menjalankan ini untuk mendapatkan PID dan waktu berlalu dari setiap proses:

$ ps -eo pid,etime

Jika Anda ingin waktu yang telah berlalu dari PID tertentu (misalnya 12345), Anda dapat melakukan sesuatu seperti:

$ ps -eo pid,etime | awk '/^12345/ {print $2}'

( Edit : Ternyata ada sintaks yang lebih pendek untuk perintah di atas; lihat jawaban mattdm )

Michael Mrozek
sumber
5

Tidak yakin mengapa ini belum disarankan: di Linux Anda dapat stat()direktori / proc / [nnn] untuk PID Anda.

Perilaku ini secara eksplisit dirancang untuk mengembalikan waktu mulai proses, yang dapat dilakukan pada resolusi tinggi, dan yang dapat dilakukan kernel secara akurat tanpa jiffies hack karena kernel dapat (jelas) hanya memeriksa informasi yang relevan. Bidang akses, modifikasi data, dan perubahan status semuanya mengembalikan waktu mulai proses.

Yang terbaik dari semuanya, Anda dapat menggunakannya stat(1)di shell, atau pengikatan yang sesuai stat(2)dari $ favorite_programming_language, sehingga Anda bahkan mungkin tidak perlu meluncurkan proses eksternal.

Perhatikan bahwa ini tidak berfungsi dengan /usr/compat/linux/procdi FreeBSD; waktu akses / modifikasi / perubahan status yang dikembalikan adalah waktu saat ini, dan waktu kelahiran adalah zaman UNIX. Cukup bodoh dukungannya tidak ada jika Anda bertanya kepada saya.

i336_
sumber
Di mana di output stat saya bisa melihat info? Saya hanya melihat Akses, Ubah, dan Ubah.
tshepang
@Tepang, perhatikan bahwa nilai-nilai itu semuanya sama, dan itu adalah waktu mulainya proses. Anda masih harus melakukan matematika, tetapi ini jelas lebih baik daripada mencoba mencari tahu jiffies seperti yang tercantum dalam jawaban saya.
mattdm
Anda menyebutnya seperti ini: stat /proc/4480Ini akan memberi Anda tanggal Kelahiran, Ubah, Ubah dan Akses proses. Jika Anda memerlukan id proses, cukup gunakan "atas"
user890332
2

Jika Anda dapat menjalankan waktu dan kemudian menjalankan perintah, Anda akan mendapatkan apa yang Anda cari. Anda tidak dapat melakukan ini terhadap perintah yang sudah berjalan.

[0]% waktu tidur 20

sleep 20 0,00s pengguna 0,00s sistem 0% cpu 20.014 total

slashdot
sumber
Apakah Anda tahu bagaimana saya bisa melakukannya pada pemantauan proses berjalan sampai berakhir?
lrkwz
1

Anda bisa mendapatkan waktu mulai proses dengan melihat statfile stat yang dihasilkan oleh proc, memformatnya menggunakan datedan mengurangi dari waktu saat ini:

echo $(( $(date +%s) - $(date -d "$(stat /proc/13494/stat | grep Modify | sed 's/Modify: //')" +%s) ))

di mana 13494pid proses Anda

kumparan
sumber
1

$ ps -eo lstart dapatkan waktu mulai

$ ps -eo etime dapatkan durasi / waktu yang berlalu

$ ps -eo pid,lstart,etime | grep 61819
  PID                   STARTED     ELAPSED
  61819 Mon Sep 17 03:01:35 2018    07:52:15

61819 adalah id proses.

Terry wang
sumber
Penggunaan lstart bisa bermasalah, ia miring
slm
1

Waktu berlalu dalam detik: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)

Shardj
sumber
Bagi saya ini adalah variasi yang sangat sedikit dari yang telah disebutkan oleh mattdm : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller
Yang itu tidak bekerja untuk saya pada contoh buruh pelabuhan Alpine saya yang sangat minim, jadi saya menulis yang ini
Shardj