1. 程式人生 > >linux shell指令碼對未定義變數的判斷以及if的用法

linux shell指令碼對未定義變數的判斷以及if的用法

環境

作業系統:win10
虛擬機器:centos7

需求

因為公司有個指令碼,是用於啟動程式的,但是每次啟動都要手動做如下兩個操作:
①先查詢之前的程序ID
②殺死之前的,在啟動新了

時間長了弄得我很煩躁,所以就琢磨下,把上面的的操作一起整合到啟動腳本里去。
最開始我是這麼寫的:

#!/bin/bash
echo "ggjob-search..."
pid=`ps -ef|grep -w ggjob-search|grep -v grep|grep -v ggjob-search.sh|awk '{printf $2}'`
echo "having kill pid:$pid
"
kill -9 $pid nohup java -Djava.ext.dirs=lib -Xms500m -Xmx500m -Dlog4j.configuration=file:/home/webuser/gogoal_platform/ggjob/config/log4j.properties -jar ggjob-search.jar config/config.properties 2>&1 >>/dev/null & echo "new pid:$!"

執行了一下,OK
結果:

ggjob-search...
having kill pid:7018
new pid:7209

假設程序早已手動殺死,在執行上面的指令碼:
結果提示:

kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

雖然不影響後面的命令,依然啟動了程式。但是總是報這個也不好看。

所以我打算加上if判斷

shell if寫法

if空格[空格判斷表示式空格];then
else
fi

對未定義變數的判斷

舉個例子:

if [ "x${pid}" != "x" ];then
echo "說明pid變數不為空"
else
echo "變數pid為空或未定義"
fi

特別注意上面if那一行是沒有一個多餘的空格;也就是說,空格是必須的,否則會報語法錯誤。

最後我調整後的指令碼為:

#!/bin/bash
echo "ggjob-search..."
pid=`ps -ef|grep -w ggjob-search|grep -v grep|grep -v ggjob-search.sh|awk '{printf $2}'`
if [ "X${pid}" != "X" ];then
echo "having kill pid:$pid"
kill -9 $pid
fi
nohup java -Djava.ext.dirs=lib -Xms500m -Xmx500m -Dlog4j.configuration=file:/home/webuser/gogoal_platform/ggjob/config/log4j.properties -jar ggjob-search.jar config/config.properties 2>&1 >>/dev/null &
echo "new pid:$!"

簡單講解:
①先執行ps -ef|grep -w ggjob-search|grep -v grep|grep -v ggjob-search.sh|awk '{printf $2}',找到我們要殺死的程序ID並賦值給變數pid
②進行判斷,要是程序沒有被殺死,就執行kill -9,進行強制殺死程序操作。
③後臺啟動程式(我這裡是啟動jar包),最後列印啟動的新ID

注意:由於我的指令碼名和查詢程序名類似,所以grep取反時,也要把指令碼本身臨時啟動的程序ID過濾掉。

這裡也貼出網上收集的一些小技巧:

判斷變數a為空最好的方法是:[  -z string ]  [  -n  string  ]
# 這種方式
if [ -z $a  ];then
echo "${LINENO} a is null"
fi
# -z 如果string長度為零,則為真
# -n 如果string長度非零,則為真

經過我大量測試:
上面的對未定義變數的判斷也可以這麼寫:

# 經過我的測試使用-n 不能判斷未定義變數
if [ ! -z ${pid} ];then
echo "說明pid變數不為空"
else
echo "變數pid為空或未定義"
fi

這是不是說明:未定義變數,使用-n判斷時,其string長度不為空,使用-z做判斷時,其string長度為空。(我也不確定)

運算子 描述 示例
-e filename 如果filename存在,則為真 [ -e /etc/profile ]
-d filename 如果filename為目錄,則為真 [ -d /tmp/mydir ]
-f filename 如果filename為常規檔案,則為真 [ -f /usr/bin/grep ]

不一一列舉了

參考連結