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


243

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.

Câu trả lời:


311

Trên Linux có pstừ 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 "$$" 

Đâu $$là bộ vi xử lý mà bạn muốn kiểm tra. Điều này sẽ trả về thời gian đã trôi qua trong định dạng [[dd-]hh:]mm:ss.

Việc sử dụng -o etimenói psrằng bạn chỉ muốn trường thời gian trôi qua và =ở cuối đoạn đó sẽ loại bỏ tiêu đề (không có, bạn nhận được một dòng có nội dung ELAPSEDvà 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ó đượ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, pschương trình lấy cái này từ /proc/$$/stat, trong đó một trong các trường (xem man proc) là thời gian bắt đầu xử lý. 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 mà hệ thống khởi động (từ /proc/stat), số lượng jiffies mỗi giây trên hệ thống này và sau đó làm toán để có được thời gian trôi qua trong một đị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.cgó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 sử dụng một kernel khác, B) sử dụng sysconf()hàm posix , đáng buồn là sử dụng 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, psmã 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, nó thuận tiện mà pslà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 statlệnh để xem ngày truy cập, sửa đổi hoặc ngày thay đổi trạng thái cho thư mục /proc/$$(trong đó 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. Đó vẫn không hoàn toàn là những gì 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ư thế date +%s --date="now - $( stat -c%X /proc/$$ ) seconds"sẽ hoạt động, nhưng nó hơi vô duyên. Một lợi thế có thể là nếu bạn sử dụng đầu ra định dạng dài như -c%xthay vì -c%X, bạn sẽ có độ phân giải lớn hơn toàn bộ số giây. 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.


1
Chào! Là etime=một lỗi đánh máy? Tôi chỉ có thể tìm thấy etimetrong các trang người đàn ông.
Kent Pawar

16
@KentPawar Đây không phải là một lỗi đánh máy. Các trống =ngăn chặn tiêu đề. Hãy thử mà không, hoặc thửps -p $$ -o etime="Silly Header Here"
mattdm

4
ps -p $ (pgrep find) -o etime =
mafrosis

1
Đẹp. Tôi thích etimesbản thân mình hơn khi đó máy có thể đọc được
Asfand Qazi

1
@alexm bồ Điều đó chỉ gọi sysconf()và do đó cung cấp cho bạn giá trị được mã hóa cứng từ thư viện C, như đã lưu ý, phải không?
mattdm

36

Di động:

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

tức là lớp vỏ đó đã đượ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 pslệnh hoặc prochệ thống tập tin của bạn .

Trong Linux, thông tin này tồn tại /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 làm thế nào để tìm giá trị jiffy từ vỏ. Thời gian bắt đầu liên quan đến thời gian khởi động (tìm thấy trong /proc/uptime).


3
Việc tìm kiếm giá trị của HZ (nghĩa là các jiffies mỗi giây) hóa ra rất phức tạp! Từ các nhận xét trong sysinfo.cgó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 (), đáng buồn thay, 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) hỏi kernel và không có giao diện chính thức để làm điều đó. Vì vậy, mã bao gồm một loạt các giá trị mà nó xác định giá trị chính xác. Ồ
mattdm

1
Trang chủ psnói rằng time"thời gian CPU tích lũy". Tôi nghĩ những gì OP đang tìm kiếm là etime, hoặc "thời gian trôi qua kể từ khi quá trình được bắt đầu". pubs.opengroup.org/onlinepub/000095399/utilities/ps.html
rinogo

1
Không phải là "di động" sau tất cả: "ps: stime: không tìm thấy từ khóa" trên FreeBSD. Nó ít nhất hỗ trợ etime, mặc dù.
n.st

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

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


2
có lẽ nên thêm một grep -v grep.
Brian

ps -o pid,comm,cmd,start,etime -p Xđể xem xét PID X.
codeforester

13

pscó một -otùy chọn để xác định định dạng đầu ra và một trong các cột có sẵn là etime. Theo trang nam:

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 )


5

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ể thư stat()mục / Proc / [nnn] cho PID của mình.

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.

Tuyệt vời nhất, bạn có thể sử dụng stat(1)tại trình bao hoặc liên kết thích hợp 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.

LƯU Ý rằng điều này không hoạt động với /usr/compat/linux/procFreeBSD; 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à thời gian UNIX. Khá ngu ngốc sự hỗ trợ không có nếu bạn hỏi tôi.


Tôi thấy thông tin ở đâu trong đầu ra của stat? Tôi chỉ thấy Truy cập, Sửa đổi và Thay đổi.
tshepang

@Tshepang Lưu ý rằng các giá trị đó đều giống nhau và chúng thời gian bắt đầu quá trình. Bạn vẫn phải làm toán, nhưng điều này chắc chắn tốt hơn là cố gắng tìm ra những câu chuyện như được ghi chú trong câu trả lời của tôi.
mattdm

Bạn gọi nó như thế này: stat /proc/4480Điều này sẽ cung cấp cho bạn ngày sinh, thay đổi, sửa đổi và truy cập của quá trình. Nếu bạn cần id quá trình, chỉ cần sử dụng "top"
user890332

2

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


Bạn có biết làm thế nào tôi có thể làm điều đó trong quá trình theo dõi quá trình đang chạy cho đến khi nó kết thúc không?
lrkwz

1

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

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

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


1

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

$ ps -eo etime có được 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.


Việc sử dụng lstart có thể có vấn đề, nó bị lệch - unix.stackexchange.com/questions/274610/ gợi
slm

1

Thời gian trôi qua trong vài giây: expr $(date +"%s") - $(stat -c%X /proc/<PID HERE>)


Đây dường như là một biến thể rất nhỏ của một thứ mà mattdm đã đề cập : date +%s --date="now - $( stat -c%X /proc/$$
Jeff Schaller

Cái đó không hoạt động với tôi trong trường hợp
docker
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.