Nói chung, đó là một ý tưởng tồi để thử cách tiếp cận đơn giản ps
và grep
cố gắng xác định xem một quy trình nhất định có đang chạy hay không.
Bạn sẽ tốt hơn nhiều khi sử dụng pgrep
cho việc này:
if pgrep "varnish" >/dev/null; then
echo "Varnish in running"
else
echo "Varnish is not running"
fi
Xem hướng dẫn cho pgrep
. Trên một số hệ thống (có thể không phải trên Linux), bạn nhận được một -q
cờ tương ứng với cùng một cờ để grep
thoát khỏi nhu cầu chuyển hướng đến /dev/null
. Ngoài ra còn có một -f
cờ thực hiện trận đấu trên dòng lệnh đầy đủ thay vì chỉ trên tên quy trình. Người ta cũng có thể giới hạn sự phù hợp với các quy trình thuộc về một người dùng cụ thể bằng cách sử dụng -u
.
Cài đặt pgrep
cũng cung cấp cho bạn quyền truy cập pkill
cho phép bạn báo hiệu các quá trình dựa trên tên của họ.
Ngoài ra, nếu đây là một trình nền dịch vụ và nếu hệ thống Unix của bạn có cách truy vấn thông tin đó (ví dụ: liệu nó có hoạt động hay không), thì đó là cách kiểm tra thích hợp .
Trên Linux, bạn có systemctl
( systemctl is-active --quiet varnish
sẽ trả về 0 nếu nó đang chạy, 3 nếu không), trên OpenBSD bạn có rcctl
, v.v.
Bây giờ đến kịch bản của bạn:
Trong kịch bản của bạn, bạn phân tích đầu ra từ ps ax
. Đầu ra này sẽ chứa tên của chính tập lệnh check_varnish_pro.sh
, rõ ràng chứa chuỗi varnish
. Điều này cung cấp cho bạn một dương tính giả. Bạn sẽ phát hiện ra điều này nếu bạn đã chạy nó mà không có -q
cờ grep
trong khi thử nghiệm.
#!/bin/bash
ps ax | grep '[v]arnish'
Chạy nó:
$ ./check_varnish_pro.sh
31004 p1 SN+ 0:00.04 /bin/bash ./check_varnish_pro.sh
Một vấn đề khác là mặc dù bạn cố gắng "che giấu" grep
quá trình khỏi bị phát hiện bởi grep
chính nó bằng cách sử dụng [v]
trong mẫu. Cách tiếp cận đó sẽ thất bại nếu bạn tình cờ chạy tập lệnh hoặc dòng lệnh trong một thư mục có tệp hoặc thư mục có tên varnish
trong đó (trong trường hợp đó bạn sẽ lại nhận được dương tính giả). Điều này là do mẫu không được trích dẫn và shell sẽ thực hiện tên tệp toàn cầu với nó.
Xem:
bash-4.4$ set -x
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep '[v]arnish'
bash-4.4$ touch varnish
+ touch varnish
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep varnish
91829 p2 SN+p 0:00.02 grep varnish
Sự hiện diện của tệp varnish
sẽ khiến shell thay thế [v]arnish
bằng tên tệp varnish
và bạn nhận được một cú đánh vào mẫu trong bảng quy trình ( grep
quy trình).