2009-04-03 37 views
5

Chúng tôi muốn xây dựng một kịch bản chạy mỗi đêm (giết chết và khởi động lại một quá trình java). Vì vậy, chúng ta cần nắm bắt số tiến trình (vì có thể có nhiều hơn một tiến trình java đang chạy). Lệnh dưới đây về cơ bản là những gì chúng ta sẽ sử dụng để có được số tiến trình, có lẽ với một regexp ở cuối grep. Trừ khi có bất kỳ đề xuất nào tốt hơn.Làm thế nào để nắm bắt được kết quả của một cuộc gọi hệ thống trong một biến hệ vỏ?

root#ps -e |grep 'java' 
18179 pts/0 00:00:43 java 

Chúng tôi muốn biết cách phân tích đầu ra ở trên và đưa nó vào biến trình bao để chúng tôi có thể sử dụng lệnh giết như sau.

kill -9 ${processid} 
wait 10 

Lưu ý1: Lý do chúng tôi không thể dựa vào lệnh dừng dịch vụ thông thường là do các quy trình đôi khi không muốn chết. Và chúng ta phải sử dụng lệnh kill một cách thủ công.

+0

Điều gì về pkill? –

Trả lời

4

Có một vài lựa chọn để giải quyết việc này. Nếu bạn đang sử dụng bash, thì biến shell '$!' sẽ chứa PID của quá trình con chia nhỏ cuối cùng. Vì vậy, sau khi bạn khởi động chương trình Java của bạn, làm một cái gì đó như:

echo $! > /var/run/my-process.pid 

Sau đó, sau khi init script của bạn dừng quá trình Java:

# Get the pidfile. 
pid=$(cat /var/run/my-process.pid) 

# Wait ten seconds to stop our process. 
for count in $(1 2 3 4 5 6 7 8 9 10); do 
    sleep 1 
    cat "/proc/$pid/cmdline" 2>/dev/null | grep -q java 
    test $? -ne 0 && pid="" && break 
done 

# If we haven't stopped, kill the process. 
if [ ! -z "$pid" ]; then 
    echo "Not stopping; terminating with extreme prejudice." 
    kill -9 $pid 
fi 

Hãy chắc chắn để loại bỏ các pidfile khi bạn đã hoàn tất.

+1

"Prejucide"? Đó là một trò đùa hay một lỗi đánh máy? –

+0

Đó là những gì xảy ra khi tôi đăng câu trả lời trước cà phê buổi sáng. –

+0

Ngoài ra, nếu bạn có lệnh 'seq', bạn có thể thực hiện 'seq 1 10' thay vì số đếm thủ công. Không phải lúc nào cũng có sẵn trên mọi hương vị của Linux. –

0

giết nó:

ps -e | grep java | cut -f1 -d' ' | xargs kill -9 

lưu trữ PID trên biến:

export JAVAPID=`ps -e | grep 'java' | cut -f1 -d' '` 

kiểm tra xem nó làm việc:

echo $JAVAPID 
3
ps aux | grep java | awk '{print $1}' | xargs kill -9 

Dưới đây là một lời giải thích:

ps aux cung cấp cho bạn một danh sách của tất cả các quá trình

grep java mang đến cho tất cả các quá trình có tên và đối số dòng lệnh chứa chuỗi "java"

bạn awk '{print $1}' phân tích cú pháp đầu ra của lệnh grep thành các cột theo khoảng trắng và chỉ in lại cột đầu tiên

xargs kill -9 chuyển từng kết quả của lệnh awk dưới dạng tham số tới lệnh kill -9

+2

Bỏ qua grep: ps aux | awk '/ java/{print $ 1}' :) – andri

+0

Cảm ơn mẹo; Tôi không biết đủ để biết làm thế nào để làm điều đó. Tôi sẽ để lại câu trả lời vì nó đơn giản hơn vì cá nhân tôi hiểu, nhưng tôi rất vui khi bạn đưa ra gợi ý đó. –

+1

Bạn không nên có một grep -v grep trong đó để ngăn chặn nó thu thập pid của grep (vì dòng lệnh của nó chứa từ java)? –

1

Bạn có thể dễ dàng lấy PID hoặc danh sách PID thành biến bằng cách sử dụng backticks và cắt (hoặc awk nếu được ưu tiên) trường PID:

[[email protected] ~]$ ps -e | grep java | cut -d' ' -f1 
12812 
12870 
13008 
13042 
13060 

Lưu ý trong ví dụ trên tôi có nhiều quá trình Java đang chạy do đó có nhiều giá trị.Nếu bạn tiết kiệm này vào một biến như sau:

JAVA_PROCS=`ps -e | grep java | cut -d' ' -f1` 

Bạn có thể lặp qua các quy trình để giết chúng nếu muốn:

for proc in $JAVA_PROCS; do 
    kill -9 $proc; 
done 

Tất nhiên, nếu bạn chỉ truy xuất một quá trình, sau đó có không cần phải lặp và bạn chỉ có thể chạy nó như:

kill -9 $JAVA_PROCS 
1

Nếu bạn làm những gì bạn đề nghị, bạn có thể sẽ nắm bắt được grep chính nó và giết chết đó (kể từ khi lệnh grep của bạn có chứa chuỗi java mà bạn ar e tìm kiếm). Bạn có thể giải quyết vấn đề này bằng cách loại trừ grep (bằng cách sử dụng grep khác!):

pid=`ps -e | fgrep java | fgrep -v grep | awk '{print $1}'` 
# check pid has a value 
# kill $pid 

Bạn cũng có thể thích ps -e -opid,args.

Cách thay thế tốt hơn là sử dụng pgrep(1) hoặc pkill(1) nếu hệ thống của bạn có chúng. Không có thêm đường ống, SEDS, awks, vết cắt, xargs:

pkill -9 java 
+0

Tôi gần như đăng cùng một điều, nhưng ps -e không liệt kê các đối số cmd (ít nhất là trên hộp của tôi) vì vậy không có nguy cơ vô tình chụp chính lệnh 'grep java' trong đầu ra grep. – Jay

+0

Phát hiện, Jay, ít nhất là cho Linux. Tôi vẫn thích pkill nhưng có vẻ như tôi là một thiểu số. –

+0

Bạn cũng có thể gắn các dấu ngoặc quanh ký tự đầu tiên trong grep, như trong grep [j] ava grep xem đó là regex và tìm kiếm j, nhưng dòng lệnh sẽ không khớp với mẫu. :) Nó làm cho tôi cảm thấy bẩn khi tôi làm điều đó, nhưng nó hoạt động tốt ... – dannysauer

0

tôi sử dụng một cái gì đó như thế này:

kill $(ps -A | grep java | cut -b 1-5) 
2

Tôi nhận ra điều này là cũ, nhưng những gì về:

pidof java | xargs kill 
Các vấn đề liên quan