導讀:
筆者編寫了一個用於控制 Java Jar 在 Linux 伺服器上啟動、停止、查詢當前狀態的 bash 簡單指令碼,分享出來希望對各位在熟悉 bash 命令時有所幫助。本文分為以下三個部分
指令碼概述
指令碼程式碼
部分 shell 命令解析
指令碼概述
admin。sh 指令碼中定義了以下四個方法:
usage() 操作提示
start() 啟動
stop() 停止
status() 狀態查詢
// 在使用指令碼前需先授權,這裡賦予最高許可權chmod 777 指令碼名// 啟動指令碼。/admin。sh start
指令碼會根據傳入的 $1 引數判斷要執行的操作。例如傳入 start 後會執行啟動邏輯:讀取 boot。pid 檔案獲取舊的 pid 並檢視相應程序是否在執行中,無執行則執行啟動命令並將新的 pid 寫入到 boot。pid 檔案中。stop 邏輯則是先判斷對應 pid 的程序是否存在,存在則 kill 掉。
指令碼程式碼
#!/bin/bash# 獲取指令碼所在的路徑,jar 包與執行指令碼在同一個路徑下,即等於獲取到了 jar 包所在路徑BOOTPATH=$(cd `dirname $0`; pwd)BOOTPID=${BOOTPATH}/boot。pidBOOTLOG=${BOOTPATH}/boot。logAPPNAME=“spider-0。0。1-SNAPSHOT”JAR_FILE=${APPNAME}“。jar”# 輸出操作提示function usage() { echo -e “\n Usage: $0 (start|stop|status)\n” exit -1}# 啟動方法function start{ oldpid=“`cat $BOOTPID`” # 透過 pid 檢視程式是否在執行中 if test `ps aux | grep -v grep | grep $oldpid | grep $APPNAME | wc -l` -gt 0 then echo “Failed to start $APPNAME ($APPNAME already running)” else ulimit -n 262140 # 執行啟動命令(配置檔案託管在 apollo 中的啟動方式) nohup java -Denv=pro -jar $JAR_FILE & # 判斷是否啟動成功 if [ $? -ne 0 ] then echo “Failed to start $APPNAME” echo “Failed to start $APPNAME” >>${BOOTLOG} else # $! 獲取 Shell 最後執行的後臺Process 的 PID, pid=“$!”; # 將新的 pid 重定向輸出到 boot。pid 檔案中覆蓋舊的 pid 進行持久化儲存 echo “$pid” > $BOOTPID # 日誌追加輸出 echo “start 。。。 ”>>${BOOTLOG} echo “pid is $pid”>>${BOOTLOG} echo “status is $?”>>${BOOTLOG} fi fi}# 停止方法function stop{ oldpid=“`cat $BOOTPID`” echo “oldpid is $oldpid”>>${BOOTLOG} if test `ps aux | grep -v grep | grep $oldpid | grep $APPNAME | wc -l` -gt 0 then kill $oldpid sleep 5 fi # 判斷是否停止成功 if [ $? -ne 0 ] then echo “Failed to stop $APPNAME” fi}# 檢視執行狀態function status{ pid=“`cat $BOOTPID`” ps aux | grep $pid | grep $APPNAME | grep -v grep >>${BOOTLOG} 2>&1 if [ $? -eq 0 ] then echo “$APPNAME is running” else echo “$APPNAME is not running” fi}# 如果輸出的引數小於 1 則輸出提示if [ $# -lt 1 ]; then usagefi# 進入到 jar 包所在路徑cd $BOOTPATH# 根據輸入的引數執行對應的操作case “$1” in start) start ;; stop) stop ;; status) status exit 0 ;; *) usage ;;esac# 列印當前狀態status
部分 shell 命令解析
1、#!/bin/bash
指令碼開頭使用 #!/bin/bash,用於指定此指令碼使用/bin/bash來解釋執行。shell 是一個命令語言直譯器,我們在提示符下輸入的每個命令都由 shell 先解釋然後傳給Linux核心,bash 是大多數 Linux 系統的預設 shell。
2、$() 和 ` `
$() 和
` `
反引號都是
用來做命令替換。會先完成它們裡面的命令列,然後將其結果輸出
[root@localhost ~]# echo today is $(date “+%Y-%m-%d”) today is 2021-10-19
3、bash 指令碼中的 $X
在 bash 指令碼中 $ 後跟隨著不同的 X 有不同的含義:
$$ :Shell本身的PID(ProcessID)
$! :Shell最後執行的後臺Process的PID
$? :最後執行的命令的結束程式碼(返回值,退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1)
$- :使用Set命令設定的Flag一覽
$* :所有引數列表。如“$*”用「“」括起來的情況、以”$1 $2 … $n“的形式輸出所有引數。
$@ :所有引數列表。如”$@“用「”」括起來的情況、以“$1” “$2” … “$n” 的形式輸出所有引數。
$# :新增到Shell的引數個數
$0 :Shell本身的檔名
$1~$n :新增到Shell的各引數值。$1是第1引數、$2是第2引數
注:
這裡就是我們實現 $1 入參,指定選擇什麼操作的具體實現方式
// 指令碼中編寫echo $1// 執行指令碼時傳入引數。/test。sh start// 這樣指令碼中輸出 $1 會被替換為 start
4、echo 用法
-e:處理特殊引數
-n:不換行輸出
echo hello // 輸出到螢幕echo hello > tmp。txt // 輸出重定向,如果 tmp。txt 存在則覆蓋,不存在則建立echo hello >> tmp。txt // 輸出追加重定向,如果 tmp。txt 存在則進行內容追加,不存在則建立
5、$(cd `dirname $0`; pwd)
這句比較有意思。其單獨在命令列輸出是毫無意義的,在指令碼檔案中才有作用,它返回的是這個指令碼檔案所在的目錄。這裡我們可以把指令碼和我們的 jar 包放在同一目錄下,這樣就可以用這句獲取到 jar 包所在的目錄了。
dirname $0 取得當前執行的指令碼檔案的父目錄
cd `dirname $0` 進入這個目錄
pwd 顯示當前的工作目錄
7、邏輯表示式在 bash 中的對應表示(透過理解英文名比較容易記住)
大於 -gt (greater than)
小於 -lt (less than)
大於或等於 -ge (greater than or equal)
小於或等於 -le (less than or equal)
不相等 -ne (not equal)
8、ll 檢視許可權
ll 檢視許可權
首列中 10 個字元用於表示不同使用者能對檔案幹什麼,三四列為使用者與使用者所在的組
第一個字元代表檔案(-)、目錄(d),連結(l)
其餘字元每3個一組(rwx),讀(r)、寫(w)、執行(x)
第一組rwx:檔案所有者的許可權是讀、寫和執行
第二組rw-:與檔案所有者同一組的使用者的許可權是讀、寫但不能執行
第三組r——:不與檔案所有者同組的其他使用者的許可權是讀不能寫和執行
9、chmod 許可權控制
如要執行 admin。sh 指令碼,我們需先透過 chmod 進行授權。
chmod 777 指令碼名 // 賦予最高許可權
-rw————- (600) —— 只有讀寫許可權
-rw-r——r—— (644) —— 只有有讀寫許可權;而屬組使用者和其他使用者只有讀許可權
-rwx———— (700) —— 只有讀、寫、執行許可權
-rwxr-xr-x (755) —— 有讀、寫、執行許可權;而屬組使用者和其他使用者只有讀、執行許可權
-rwx——x——x (711) —— 有讀、寫、執行許可權;而屬組使用者和其他使用者只有執行許可權。
10、grep 管道用法
|grep firefox 過濾關鍵字
|grep firefox |wc -l 關鍵字統計
|grep firefox |grep firefox test 多重過濾
|grep -v grep 去除包含 grep 的程序行 ,使結果更為準確
最後
感謝您的閱讀,如果喜歡本文歡迎關注和轉發,轉載需註明出處,本頭條號將持續分享IT技術知識。對於文章內容有其他想法或意見建議等,歡迎提出共同討論共同進步。