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 killvà 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 $PIDtươ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 0trả 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?
-pnày là không cần thiết, ít nhất là trong trường hợp đó. ps $PIDcó 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
pscá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.
$PIDtrố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/$PIDthư 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/exekhô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 falsekết quả. Hãy thử [ -h /proc/$PID/exe ].
Có vẻ như bạn muốn
wait $PID
Nó sẽ trở lại khi $pidkế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 $pidvì 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 killtươ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.
pidofkhô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ị Pidsau này)if pidof 'process_name'; then...
pidofví dụ đầy hiểu lầm về cách testhoạ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 $?