Shell-Script

為什麼我得到不同的 ps 退出狀態 |grep 在腳本中?

  • February 22, 2018

我在腳本下面執行:

#!/bin/bash

ps ax  | grep -q [v]arnish
if [ $? -eq 0 ];then
       echo varnish is running...
       exit 0
else
       echo "Critical : varnish is not running "
       exit 2
fi

輸出類似於::

[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0

當我在命令行中執行相同時,我的退出狀態為 1:

[root@server ~]# ps ax  | grep -q [v]arnish; echo $?
1

這種情況就像清漆沒有安裝在伺服器中一樣。該腳本在安裝了 varnish 的伺服器上執行良好。

為什麼使用腳本和命令行執行時退出狀態不同?如何改進這個腳本?

當您執行名為check_varnish_pro.shtest的腳本時

ps ax  | grep -q [v]arnish

成功是因為有一個名為check_varnish_pro的腳本正在執行。

一般來說,嘗試使用簡單方法psgrep嘗試確定給定程序是否正在執行是一個壞主意。

你最好使用pgrep這個:

if pgrep "varnish" >/dev/null; then
 echo "Varnish in running"
else
 echo "Varnish is not running"
fi

參見手冊pgrep。在某些系統上(可能不在 Linux 上),您會得到一個-q標誌,該標誌對應於相同的標誌,grep無需重定向到/dev/null. 還有一個-f標誌可以在完整的命令行上執行匹配,而不僅僅是在程序名稱上。也可以將匹配限制為屬於特定使用者的程序,使用-u.

安裝pgrep還允許您訪問pkill允許您根據程序名稱發出信號的程序。

此外,如果這是一個服務守護程序,並且如果您的 Unix 系統有一種方法可以查詢它的資訊(例如,它是否啟動和執行),那麼這是檢查它的正確方法。

在 Linux 上,你有systemctlsystemctl is-active --quiet varnish如果它正在執行,將返回 0,否則返回 3),在 OpenBSD 上你有rcctl,等等。


現在到你的腳本:

在您的腳本中,您解析來自ps ax. 此輸出將包含腳本本身的名稱,check_varnish_pro.sh顯然包含字元串varnish。這會給你一個誤報。-q如果您在測試時不帶標誌執行它,您就會發現這一點grep

#!/bin/bash
ps ax | grep '[v]arnish'

執行它:

$ ./check_varnish_pro.sh
31004 p1  SN+     0:00.04 /bin/bash ./check_varnish_pro.sh

另一個問題是,儘管您嘗試通過在模式中使用來“隱藏”grep程序,使其不被grep自身檢測到。[v]如果您碰巧在其中包含文件或目錄的目錄中執行腳本或命令行,則該方法將失敗varnish(在這種情況下,您將再次得到誤報)。這是因為該模式未加引號,shell 將使用它執行文件名通配。

看:

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

該文件的存在varnish將導致 shell 替換[v]arnish為文件名,並且您在程序表(程序)varnish中的模式上得到了命中。grep

引用自:https://unix.stackexchange.com/questions/337309