Câu trả lời:
Để kiểm tra sự tồn tại của một quá trình, sử dụng
kill -0 $pid
Nhưng đúng như @unwind đã nói, dù sao bạn cũng sẽ giết nó, chỉ cần
kill $pid
hoặc bạn sẽ có một điều kiện cuộc đua.
Nếu bạn muốn bỏ qua đầu ra văn bản của kill
và làm một cái gì đó dựa trên mã thoát, bạn có thể
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill
được đặt tên sai ở chỗ nó không nhất thiết phải giết quá trình. Nó chỉ gửi quá trình một tín hiệu. kill $PID
tương đương với kill -15 $PID
, nó gửi tín hiệu 15, SIGTERM đến tiến trình, đây là một lệnh để chấm dứt. Không có tín hiệu 0, đó là một giá trị đặc biệt kill
để chỉ kiểm tra xem tín hiệu có thể được gửi đến quá trình hay không, điều này dành cho hầu hết các mục đích tương đương ít nhiều với việc kiểm tra xem nó có tồn tại hay không. Xem linux.die.net/man/2/kill và linux.die.net/man/7/signal
kill -0
, trên thực tế, tôi phải làm điều này: kill -0 25667 ; echo $?
- và sau đó nếu tôi được 0
trả lại, thì quá trình với PID đó có thể bị giết; và nếu quá trình PID (nói) không tồn tại, thì $?
sẽ có 1
, cho thấy sự thất bại. Đúng không?
Cách tốt nhất là:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
Vấn đề với:
kill -0 $PID
là mã thoát sẽ khác không ngay cả khi pid đang chạy và bạn không có quyền giết nó. Ví dụ:
kill -0 1
và
kill -0 $non-running-pid
có một mã thoát không thể phân biệt (khác không) cho một người dùng bình thường, nhưng quá trình init (PID 1) chắc chắn đang chạy.
Các câu trả lời thảo luận về điều kiện giết và chủng tộc là hoàn toàn chính xác nếu cơ thể của bài kiểm tra là "giết". Tôi đã tìm kiếm chung chung " làm thế nào để bạn kiểm tra sự tồn tại của PID trong bash ".
Phương thức / Proc rất thú vị, nhưng trong một số trường hợp, phá vỡ tinh thần của sự trừu tượng lệnh "ps", tức là bạn không cần phải tìm trong / Proc vì nếu Linus quyết định gọi tệp "exe" thì sao?
-p
này là không cần thiết, ít nhất là trong trường hợp đó. ps $PID
có kết quả chính xác như nhau.
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
hoặc là
if [ -n "$(ps -p $PID -o pid=)" ]
Ở dạng sau, -o pid=
là một định dạng đầu ra để chỉ hiển thị cột ID quá trình không có tiêu đề. Các trích dẫn là cần thiết cho toán tử chuỗi không trống -n
để đưa ra kết quả hợp lệ.
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
các tùy chọn và tính năng có xu hướng khác nhau giữa các nền tảng, vì vậy nó vẫn không hoàn toàn di động.
$PID
trống thì [ -e /proc/$PID ]
vẫn trả về true, vì /proc/
thư mục vẫn tồn tại.
Bạn có hai cách:
Hãy bắt đầu bằng cách tìm kiếm một ứng dụng cụ thể trong máy tính xách tay của tôi:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
Tất cả các ví dụ bây giờ sẽ tìm kiếm PID 3358.
Cách thứ nhất : Chạy "ps aux" và grep cho PID trong cột thứ hai. Trong ví dụ này tôi tìm firefox, và sau đó là PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
Vì vậy, mã của bạn sẽ là:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Cách thứ hai : Chỉ cần tìm một cái gì đó trong /proc/$PID
thư mục. Tôi đang sử dụng "exe" trong ví dụ này, nhưng bạn có thể sử dụng bất cứ thứ gì khác.
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
Vì vậy, mã của bạn sẽ là:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
BTW: có chuyện gì với kill -9 $PID || true
?
BIÊN TẬP:
Sau khi suy nghĩ về nó trong vài tháng .. (khoảng 24 ...) ý tưởng ban đầu tôi đưa ra ở đây là một bản hack hay, nhưng rất khó tin. Mặc dù nó dạy một vài chi tiết triển khai của Linux, nhưng nó sẽ không hoạt động trên Mac, Solaris hoặc * BSD. Nó thậm chí có thể thất bại trên các nhân Linux trong tương lai. Vui lòng - sử dụng "ps" như được mô tả trong các phản hồi khác.
/proc/$PID/exe
không phải là một tập tin thông thường Vì vậy, [ -f /proc/$PID/exe ]
sẽ luôn trả về một false
kết quả. Hãy thử [ -h /proc/$PID/exe ]
.
Có vẻ như bạn muốn
wait $PID
Nó sẽ trở lại khi $pid
kết thúc.
Nếu không bạn có thể sử dụng
ps -p $PID
để kiểm tra xem quy trình có còn tồn tại không (điều này hiệu quả hơn kill -0 $pid
vì nó sẽ hoạt động ngay cả khi bạn không sở hữu pid).
pid 123 is not a child of this shell
Tôi nghĩ rằng đó là một giải pháp tồi, mở ra cho các điều kiện chủng tộc. Điều gì xảy ra nếu quá trình chết giữa thử nghiệm của bạn và lời kêu gọi giết của bạn? Sau đó giết sẽ thất bại. Vậy tại sao không thử giết trong mọi trường hợp và kiểm tra giá trị trả về của nó để tìm hiểu xem nó đã đi như thế nào?
kill -9
. Điều đó ngay lập tức giết chết quá trình cho nó không có cơ hội để làm sạch sau đó. Thay vào đó sử dụng kill
tương đương với kill -15
. Nếu điều đó không hiệu quả, bạn nên tìm hiểu lý do tại sao và chỉ là lần sử dụng cuối cùng kill -9
.
Ở đây tôi lưu trữ PID trong một tệp có tên .pid (là loại like / run / ...) và chỉ thực thi tập lệnh nếu chưa được thực thi.
#!/bin/bash
if [ -f .pid ]; then
read pid < .pid
echo $pid
ps -p $pid > /dev/null
r=$?
if [ $r -eq 0 ]; then
echo "$pid is currently running, not executing $0 twice, exiting now..."
exit 1
fi
fi
echo $$ > .pid
# do things here
rm .pid
lưu ý: có một điều kiện cuộc đua vì nó không kiểm tra xem pid đó được gọi như thế nào. nếu hệ thống được khởi động lại và .pid tồn tại nhưng được sử dụng bởi một ứng dụng khác, điều này có thể dẫn đến 'hậu quả không lường trước'.
Ví dụ: trong GNU / Linux, bạn có thể sử dụng:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
Hoặc một cái gì đó như
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
và điều đó cho bạn thấy tên của ứng dụng, chỉ tên không có ID.
pidof
không trả về số âm, vì một PID âm không có ý nghĩa gì và bạn không thể giết init
, do đó, điều kiện của bạn không có ý nghĩa gì (và bên cạnh đó, bạn cần phải thoát khỏi >
để ngăn nó thực hiện chuyển hướng). Bạn muốn kiểm tra một kết quả trống, nhưng tất nhiên, giống như bất kỳ công cụ tử tế nào, pidof
đặt mã thoát để cho bạn biết liệu nó có hoạt động hay không, vì vậy giải pháp thích hợp là if Pid=$(pidof 'process_name'); then ...
hoặc (nếu bạn sẽ không cần giá trị Pid
sau này)if pidof 'process_name'; then...
pidof
ví dụ đầy hiểu lầm về cách test
hoạt động của bash . gnu.org/software/bash/manual/html_node/ từ
mã bên dưới kiểm tra nếu quá trình của tôi đang chạy, nếu vậy không làm gì.
hãy kiểm tra tin nhắn mới từ Amazon SQS mỗi giờ và chỉ khi quá trình không chạy.
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?