it-swarm-vi.com

Làm thế nào để kiểm tra một quá trình đã chạy được bao lâu?

Tôi muốn tránh làm điều này bằng cách khởi chạy quy trình từ một ứng dụng giám sát.

250
tshepang

Trên Linux có ps từ procps(-ng) (và hầu hết các hệ thống khác vì điều này được chỉ định bởi POSIX):

ps -o etime= -p "$$" 

Trong đó $$ Là PID của quá trình bạn muốn kiểm tra. Điều này sẽ trả về thời gian đã trôi qua ở định dạng [[dd-]hh:]mm:ss.

Việc sử dụng -o etime Sẽ cho ps rằng bạn chỉ muốn trường thời gian trôi qua và = Ở cuối tiêu đề đó (không có, bạn nhận được một dòng có nội dung ELAPSED và sau đó là thời gian trên dòng tiếp theo, với, bạn chỉ nhận được một dòng với thời gian).

Hoặc, với các phiên bản mới hơn của bộ công cụ Procps-ng (3.3.0 trở lên) trên Linux hoặc trên FreeBSD 9.0 trở lên (và có thể cả các phiên bản khác), hãy sử dụng:

ps -o etimes= -p "$$"

(có thêm s) để có thời gian được định dạng chỉ trong vài giây, điều này hữu ích hơn trong các tập lệnh.

Trên Linux, chương trình ps nhận được điều này từ /proc/$$/stat, Trong đó một trong các trường (xem man proc) Là thời gian bắt đầu quá trình. Thật không may, điều này được chỉ định là thời gian trong jiffies (bộ đếm thời gian tùy ý được sử dụng trong nhân Linux) kể từ khi hệ thống khởi động. Vì vậy, bạn phải xác định thời gian hệ thống khởi động (từ /proc/stat), Số lượng jiffies mỗi giây trên hệ thống này, sau đó thực hiện phép toán để lấy thời gian trôi qua theo định dạng hữu ích.

Nó trở nên phức tạp đến nực cười khi tìm thấy giá trị của HZ (nghĩa là jiffies mỗi giây). Từ các nhận xét trong sysinfo.c Trong gói Procps, người ta có thể A) bao gồm tệp tiêu đề kernel và biên dịch lại nếu một kernel khác được sử dụng, B) sử dụng hàm posix sysconf(), trong đó, thật đáng buồn, sử dụng một giá trị được mã hóa cứng được biên dịch vào thư viện C hoặc C) yêu cầu kernel, nhưng không có giao diện chính thức để làm điều đó. Vì vậy, mã ps bao gồm một loạt các giá trị mà nó xác định giá trị chính xác. Ồ.

Vì vậy, thật tiện lợi khi ps làm tất cả cho bạn. :)

Như người dùng @ 336_ lưu ý, trên Linux (đây không phải là di động), bạn có thể sử dụng lệnh stat để xem ngày truy cập, sửa đổi hoặc ngày thay đổi trạng thái cho thư mục /proc/$$ (Một lần nữa $$ Là quá trình quan tâm). Tất cả ba số phải giống nhau, vì vậy

stat -c%X /proc/$$

sẽ cho bạn thời gian mà quá trình $$ bắt đầu, tính bằng giây kể từ Kỷ nguyên. Điều đó vẫn không hoàn toàn như bạn muốn, vì bạn vẫn cần phải làm toán để trừ đi từ thời điểm hiện tại để có được thời gian trôi qua - tôi đoán một cái gì đó như date +%s --date="now - $( stat -c%X /proc/$$ ) seconds" sẽ hoạt động, nhưng nó hơi vô duyên. Một ưu điểm có thể là nếu bạn sử dụng đầu ra định dạng dài như -c%x Thay vì -c%X, Bạn sẽ có độ phân giải lớn hơn số giây toàn bộ. Nhưng, nếu bạn cần điều đó, có lẽ bạn nên sử dụng phương pháp kiểm tra quy trình vì thời gian chạy lệnh stat sẽ can thiệp vào độ chính xác.

324
mattdm

Di động:

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

tức là Shell đã được bắt đầu vào ngày 30 tháng 1 và tổng cộng khoảng 6 giây thời gian CPU.

Có thể có nhiều cách chính xác hơn hoặc dễ phân tích hơn nhưng ít di động hơn để có được thông tin này. Kiểm tra tài liệu của lệnh ps hoặc hệ thống tập tin proc của bạn.

Trong Linux, thông tin này tồn tại trong /proc/$pid/stat .

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

Thời gian CPU là trong jiffies; Tôi không biết cách tìm ra giá trị Jiffy từ Shell. Thời gian bắt đầu liên quan đến thời gian khởi động (được tìm thấy trong /proc/uptime).

ps -eo pid,comm,cmd,start,etime | grep -i X

X là tên của quá trình

19
mezi

ps mất -o tùy chọn để chỉ định định dạng đầu ra và một trong các cột có sẵn là etime. Theo trang người đàn ông:

etime - thời gian trôi qua kể từ khi quá trình được bắt đầu, ở dạng [[dd-] hh:] mm: ss.

Do đó, bạn có thể chạy cái này để có được thời gian trôi qua của mỗi quá trình:

$ ps -eo pid,etime

Nếu bạn muốn thời gian trôi qua của một PID cụ thể (ví dụ: 12345), bạn có thể làm một cái gì đó như:

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

( Chỉnh sửa : Hóa ra có một cú pháp ngắn hơn cho lệnh trên; xem câu trả lời của mattdm )

13
Michael Mrozek

Không chắc chắn lý do tại sao điều này chưa được đề xuất: trên Linux bạn có thể stat() thư mục/Proc/[nnn] cho PID của bạn.

Hành vi này được thiết kế rõ ràng để trả về thời gian bắt đầu quá trình, có thể thực hiện ở độ phân giải cao và hạt nhân có thể thực hiện chính xác mà không cần hack jiffies vì ​​kernel có thể (rõ ràng) chỉ cần kiểm tra thông tin liên quan. Các trường truy cập, sửa đổi dữ liệu và thay đổi trạng thái đều trả về thời gian bắt đầu quá trình.

Tốt nhất, bạn có thể sử dụng stat(1) tại Shell hoặc liên kết thích hợp với stat(2) từ $ favour_programming_lingu, do đó bạn thậm chí không cần phải khởi chạy một quy trình bên ngoài.

GHI CHÚ rằng điều này không không làm việc với /usr/compat/linux/proc trên FreeBSD; thời gian truy cập/sửa đổi/thay đổi trạng thái được trả về là thời gian hiện tại và thời gian sinh là Kỷ nguyên UNIX. Khá ngu ngốc sự hỗ trợ không có nếu bạn hỏi tôi.

5
i336_

Nếu bạn có thể chạy thời gian và sau đó thực hiện một lệnh, bạn sẽ nhận được chính xác những gì bạn đang tìm kiếm. Bạn không thể làm điều này chống lại một lệnh đã chạy.

[0]% thời gian ngủ 20

ngủ 20 0,00 giây người dùng 0,00s hệ thống 0% cpu 20.014 tổng

2
slashdot

$ ps -eo lstart nhận thời gian bắt đầu

$ ps -eo etime nhận thời lượng/thời gian trôi qua

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

61819 là id quá trình.

2
Terry wang

Thời gian trôi qua tính bằng giây: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)

1
Shardj

bạn có thể nhận được thời gian bắt đầu của quá trình bằng cách xem stat của tệp stat được tạo bởi proc, định dạng nó bằng cách sử dụng date và trừ nó khỏi thời điểm hiện tại:

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

ở đâu 13494 là quá trình của bạn

1
bobbins