linux 環境啟動jar服務, 啟動腳本詳細解釋

来源:https://www.cnblogs.com/yswb/archive/2023/02/28/17165190.html
-Advertisement-
Play Games

問題產生: 作者最近在搭建Hadoop+Hive集群時,將NameNode、DataNode、Rm全部部署到一臺物理機上,查詢量較大時連接掛掉。 問題定位: 使用JPS命令查看Metastore服務正常運行,hive2--Runjar掛掉。重啟之後,過段時間又會掛掉。 Linux 內核有個機制叫OO ...


掰碎了講一個jar包啟動文件.

  • 當前服務目錄如下
# ls /easy/test/info/ -> bin  mytest.jar
#  ls /easy/test/info/bin/ -> spring-boot.sh

spring-boot.sh 文件內容如下

#!/bin/bash
# 環境索引: 標識解釋器為bash ./當前文件 等同於 sh 當前文件
# 本次解析執行命令= ./easy/test/info/bin/spring-boot.sh  start
JAVA_OPTIONS_INITIAL=-Xms500M
JAVA_OPTIONS_MAX=-Xmx1000M
# 定義變數: 註意=左右不要有空格
BINPATH=$(cd `dirname $0`; pwd)
# 獲取腳本所在的項目名稱
# $0  獲取當前腳本本身的名字,其他包執行則包含到當前文件的路徑
# dirname 命令去除文件名中的非目錄部分,僅顯示與目錄有關的內容
# $()和反引號``的作用結果相同都是用來作命令替換的,通俗來講就是把命令執行後的結果作為參數返回
# pwd 命令用於顯示工作目錄的絕對路徑名稱
# 先執行 dirname $0 獲取當前目錄名稱,
# 再執行cd 切換到當前目錄,
# ; 分號; 用分號隔開兩個命令
# 再執行pwd, 用BINPATH 接受pwd返回結果.
# $0 ==>            ./easy/test/info/bin/spring-boot.sh
# `dirname $0` ==>  ./easy/test/info/bin/ 
# BINPATH==>        /easy/test/info/bin

if [ $(ls ${BINPATH%/bin*}|grep .*.jar|wc -l) -gt 1 ] ;then
# 字元串截取:  ${parameter%word} # 刪除匹配尾碼
#   ${BINPATH%/bin*} 獲取BINPATH 刪除/bin 後面部分
# grep 匹配
# wc 計數
# -gt 大於
# if 流程判斷
# 獲取腳本上級的.jar 結尾文件是否>1個.
	echo "目錄中含有多個jar文件"
	exit 0
fi
_JAR_KEYWORDS=$(ls ${BINPATH%/bin*}|grep .*.jar)
# 獲取當前jar包名稱(mytest.jar)

if [ "$_JAR_KEYWORDS" =  "" ] ;then
	echo "${BINPATH%/bin*}下未找到jar包!!"
	exit 0
fi
APP_NAME=${_JAR_KEYWORDS%.jar*}
# 字元串截取:  ${parameter%word} # 刪除匹配尾碼
#   ${_JAR_KEYWORDS%.jar*} 去掉jar包的.jar尾碼, 賦值給appName欄位(mytest)
if [ $1 == "start" ] ;then
	echo "當前啟動的項目為:$APP_NAME,項目所在目錄:${BINPATH%/bin*}"
fi
# 查詢進程,去掉grep查詢, 取第二位(pid)
PID=$(ps aux | grep ${_JAR_KEYWORDS} | grep -v grep | awk '{print $2}' )
# ps    進程查看
# | grep -v grep 排除grep 進程,即當前的ps查詢進程
# awk 行處理器, awk '{print $2}' 輸出第2行數據, 即pid行.
function check_if_process_is_running {
    if [ "$PID" = "" ]; then
        return 1
    fi
    ps -p $PID | grep "java"
    # ps 進程查看, 根據pid查看進程
    return $?
    # $? 上一指令的返回值,成功是0,不成功是1。
}

case "$1" in
status)
# case 選擇命令
# $1 執行該文件的第一個參數.
if check_if_process_is_running
then
echo -e "\033[32m $APP_NAME is running \033[0m"
# echo -e 轉義輸出
# \033[xm 控制字元 \033[32m 指定當前文本綠色展示.
else
echo -e "\033[32m $APP_NAME not running \033[0m"
fi
;;
stop)
if ! check_if_process_is_running
then
echo -e "\033[32m $APP_NAME already stopped \033[0m"
exit 0
fi
kill -9 $PID
# kill 殺死指定進程
echo -e "\033[32m Waiting for process to stop \033[0m"
NOT_KILLED=1
for i in {1..20}; do
if check_if_process_is_running
then
echo -ne "\033[32m . \033[0m"
# echo -ne  轉義輸出, 不進行換行
sleep 1
else
NOT_KILLED=0
fi
done
echo
if [ $NOT_KILLED = 1 ]
then
echo -e "\033[32m Cannot kill process \033[0m"
exit 1
fi
echo -e "\033[32m $APP_NAME already stopped \033[0m"
;;
start)
if [ "$PID" != "" ] && check_if_process_is_running
then
echo -e "\033[32m $APP_NAME already running \033[0m"
exit 1
fi
cd ${BINPATH%/bin*}
JAVA_MEM_SIZE_OPTS="-Xmx256m -Xms128m -Xmn256m -XX:PermSize=200m -XX:MaxPermSize=200M -Xss256k"
JAVA_MEM_OPTS=" -server $JAVA_MEM_SIZE_OPTS -XX:SurvivorRatio=2 -XX:+UseParallelGC "
nohup java -jar $JAVA_OPTIONS_INITIAL $JAVA_OPTIONS_MAX $_JAR_KEYWORDS --debug> 123.log 2>&1 &
#nohup 不掛起執行
echo -ne "\033[32m Starting \033[0m"
for i in {1..20}; do
# 通配符(globbing) {1..20} 迴圈20次,分別取1,2,3...19,20
echo -ne "\033[32m.\033[0m"
sleep 1
done
if check_if_process_is_running
then
echo -e "\033[32m $APP_NAME fail \033[0m"
else
echo -e "\033[32m $APP_NAME started \033[0m"
fi
;;
restart)
$0 stop
# 重新執行該文件, 傳遞參數為 stop
if [ $? = 1 ]
then
exit 1
fi
$0 start
# 重新執行該文件, 傳遞參數為 start
;;
*)
# case 未匹配, 走的預設模組
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac

exit 0

  • 環境索引

    開頭"#!/bin/bash"作用
    這行註釋的作用就是聲明解析當前文件要使用的解釋器
    
    • 不聲明解釋器的方式
    執行: sh xxx
    
    • 聲明"#!/bin/bash"
    執行: ./xxx(等同於 sh xxx)
    
    • 聲明"#!/bin/cat"
    執行: ./xxx(等同於 cat xxx)
    
  • 變數定義和使用

    • 定義變數
    定義變數, 變數名不加美元符號$
        your_name="easy.com"
    註意,變數名和等號之間不能有空格,這可能和你熟悉的所有編程語言都不一樣。
    
    • 使用一個定義過的變數
    在變數名前面加美元符號即可:
        your_name="qinjx"
        echo $your_name
        echo ${your_name}
    變數名外面的花括弧可選,加花括弧是為了幫助解釋器識別變數的邊界,比如下麵這種情況
        for skill in Ada Coffe Action Java; do
            echo "I am good at ${skill}Script"      # 識別為: skill
            echo "I am good at $skillScript"        # 自動識別為: skillScript
        done
    
  • linux中$用法

    • $0, $?等表示各種參數
    $0:bash文件名。
    $?:上一指令的返回值,成功是0,不成功是1。
    $1,$2,$3....:表示命令後接的第幾個參數
    
    • ${}, 獲取變數的值
    ${var_name} 跟光$var_name差不多
    但是用${ }會比較精確的界定變數名稱的範圍。
    
    • $(),`` 命令替換
    在bash中,$( )與` `(反引號)都是用來作命令替換的,執行括弧或者反引號中的命令, 然後返回結果。
    比如:echo "present dir is $(pwd)"
    但是$()和``還是稍有不同的,在多層次的複合替換中,``必須要額外的跳脫處理(反斜線),而$( )則不用,比較直觀。
    # 將cmd1執行結果作為cmd2參數,再將cmd2結果作為cmd3的參數
    cmd1 $(cmd2 $(cmd3))
    # 如果是用反引號,直接引用是不行的,還需要作跳脫處理
    cmd1 `cmd2 \`cmd3\``
    
  • Linux 特殊字元用法(;,|,&,||,&&)

    ;   分號; 用分號隔開兩個命令,每條命令按照從左到右的順序,順序執行,彼此之間不關心是否失敗,所有命令都會執行。
    |   管道符; 上一條命令的輸出,作為下一條命令參數
        示例: grep "123" 1.txt | wc -l
    &   放在啟動命令參數後面表示設置此進程為後臺進程
    ||  邏輯或
        只有在 || 左邊的命令返回假,右邊的命令才會被執行。
        只要有一個命令返回真,後面的命令都不會被執行。一直到返回真的地方停止執行
    &&  邏輯與
        前一條命令執行成功,才會執行下一條命令。
  • linux ${}文本處理

    • 獲取字元串長度 $
    • 字元串切片$
    將字元串變數a從第b個位置開始向後截取c個字元,b是指下標,下標從0開始
    
    • 替換字元串$
    將變數a中的b全部替換為c,開頭一個正斜杠為只匹配第一個字元串,兩個正斜杠為匹配所有字元。
    b支持正則示例: echo ${a//[^0-9]/c}
    
    • 字元串截取
    ${parameter#word} # 刪除匹配首碼
    ${parameter##word}
    ${parameter%word} # 刪除匹配尾碼
    ${parameter%%word}
    # 去掉左邊,#最短匹配模式,##最長匹配模式。
    % 去掉右邊,%最短匹配模式,%%最長匹配模式。
    
    • 變數狀態賦值
    ${VAR:-string} 如果 VAR 變數為空則返回 string
    ${VAR:+string} 如果 VAR 變數不為空則返回 string
    ${VAR:=string} 如果 VAR 變數為空則重新賦值 VAR 變數值為 string
    ${VAR:?string} 如果 VAR 變數為空則將 string 輸出到 stderr
    
  • 基本運算符

    • 算術運算符(+ - * / % = == !=)
    • 關係運算符
    -eq //equals等於
    -ne //no equals不等於
    -gt //greater than 大於
    -lt //less than小於
    -ge //greater equals大於等於
    -le //less equals小於等於
    
    • 布爾運算符
    !	非運算,表達式為 true 則返回 false,否則返回 true。
    -o	或運算,有一個表達式為 true 則返回 true。
    -a	與運算,兩個表達式都為 true 才返回 true。
    
    • 整數運算命令(())
    雙小括弧 (( )) 是 Bash Shell 中專門用來進行整數運算的命令
    註意:(( )) 只能進行整數運算,不能對小數(浮點數)或者字元串進行運算。後續講到的 bc 命令可以用於小數運算。
    在 (( )) 中使用變數無需加上$首碼,(( )) 會自動解析變數名,這使得代碼更加簡潔,也符合程式員的書寫習慣
    這種寫法可以在計算完成後給變數賦值
        示例: ((b=a-15)) 將 a-15 的運算結果賦值給變數 b。
        使用變數時不用加$首碼,(( )) 會自動解析變數名.
    可以在 (( )) 前面加上$符號獲取 (( )) 命令的執行結果,也即獲取整個表達式的值
        示例: b=$((a-15)) 將 a-15 的運算結果賦值給變數 b。
        類似 c=((a+b)) 這樣的寫法是錯誤的,不加$就不能取得表達式的結果
    (( )) 也可以進行邏輯運算,在 if 語句中常會使用邏輯運算。
        示例: ((a>7 && b==c)) 不用寫 -gt -eq 等命令, 直接用數學寫法即可.
        
        
    
  • 流程式控制制

    • if 判斷
    if xxx ; then xxx ; fi
    if xxx ; then xxx ; else xxx ; fi
    if xxx ; then xxx ; elif xxx ; then xxx ; else xxx ; fi
    
    • for 迴圈
    for xxx in xxx; do xxx done;
    
    • while 迴圈執行
    while xxx ; do xxx done;
    while true;do curl --request POST   --url http://127.0.0.1:8111/api/healthy/post;   sleep 1; done
    
    • case 選擇
    case xxx in x)xxx; ;;*)xxx; ;;esac
    每個 case 取值後面必須為單詞 in, 分支用右圓括弧開始,用兩個分號 ;; 表示 break,即執行結束; * 匹配所有
    
    • 無限迴圈
    while:; do xxx ;done
    while true;do xxx ;done
    for ((;;));do xxx ;done
    
    • 跳出迴圈(break,continue)
  • 常用命令

    • pwd:(print work directory)命令用於顯示工作目錄的絕對路徑名稱。
    • grep 命令用於查找文件里符合條件的字元串
    詳見: grep --help
    具體見: info grep
    
    • wc命令用於計算字數。
    詳情見: wc --help
    具體見: info wc
    
    -c或--bytes或--chars 只顯示Bytes數。
    -l或--lines 顯示行數。
    -w或--words 只顯示字數。
    
    • awk 行處理器
    詳情見: awk
    具體見: info awk
    示例: | awk '{print $1}' 以空格/tab作為分隔符,獲取第2個字元
    
    • ps 進程查看器
    詳情見: for i in s l o t m a ; do ps --help $i ;done
    示例: 
    ps -ef |grep xxx
    ps aux |grep xxx
    
    • echo 字元串輸出
    詳情見: help echo
    選項:
          -n	不要追加換行
          -e	啟用下列反斜杠轉義的解釋
          -E	顯式地抑制對於反斜杠轉義的解釋
    echo "string"       # 輸出字元串
    echo -e "開啟轉義"
    echo -e "xxx\n"     # 添加換行
    ehco -e "xxx\c"     # 強制不換行
    
    • \033[xxxm 控制字元
    多個參數採用;分割.
    \033[0m	關閉所有屬性
    \033[1m	設置高亮度
    \033[30~37m	設置前景色
    \033[40~47;m	設置背景色
    示例: 
    echo -e "\033[31;1m 這是一個紅色高亮文字 \033[0m"
    顏色編碼示例:
    黑=30,40
    紅=31,41
    綠=32,42
    黃=33,43
    藍=34,44
    紫=35,45
    靛藍=36,46
    白=37,47
    
    • 通配符(globbing)
    示例:
    # for i in {1..20};do echo -n  "$i," ;done
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
    # ls {ex{1..3},ex4}.sh
    ex1.sh  ex2.sh  ex3.sh  ex4.sh  
    # ls {ex[1-3],ex4}.sh    
    ex1.sh  ex2.sh  ex3.sh  ex4.sh   
    
    
    • sleep 睡眠等待
    詳見: sleep --help
    sleep 1 # 程式睡眠1秒
    
    
    • nohup 不掛起(no hang up)
    用於在系統後臺不掛斷地運行命令,退出終端不會影響程式的運行
    詳見: nohup --help
    示例1:
    nohup COMMAND > nohup.out 2>&1 &
    2>&1 解釋:
        將標準錯誤 2 重定向到標準輸出 &1 ,標準輸出 &1 再被重定向輸入到 nohup.out 文件中。
        0 – stdin (standard input,標準輸入)
        1 – stdout (standard output,標準輸出)
        2 – stderr (standard error,標準錯誤輸出)
    示例2:
    nohup COMMAND > /dev/null 2>&1 & # /dev/null 文件不存在則不進行控制台信息輸出.
    
    • kill 殺死進程
    詳見: kill --help
    信號名稱: kill -l
        常見信號:
            1 (HUP):重新載入進程。
            9 (KILL):殺死一個進程。
            15 (TERM):正常停止一個進程。
    強制殺死指定進程
    kill -9 $(ps -ef |grep spring-boot)
    

日常用shell命令集合

  • 測試環境,docker部署, 每次啟動生成一個新的日誌文件包, 想直接自動選擇到最後一個生成的文件包併進入
cd `ls -t`
# 效果: ll -lrt 選擇最後一個文件夾, copy文件名稱 cd ${fileName} 回車.
  • 殺死指定項目啟動的進程
kill -9 $(ps -ef |grep xxxxxx)
# 效果: ps -ef |grep xxxxx 選擇pid行, 執行 kill -9 ${pid}
  • 將指定文件copy到jar包內並重新啟動
ll
mkdir BOOT-INF
mkdir BOOT-INF/lib
mkdir  BOOT-INF/classes
yes | mv *SNAPSHOT.jar BOOT-INF/lib
yes | mv *.properties BOOT-INF/classes
yes | mv *.yml BOOT-INF/classes
yes | mv *.xml BOOT-INF/classes
ll
jar uvf0 *.jar BOOT-INF/
rm -rf  BOOT-INF
ll
sh bin/spring-boot.sh restart
date
# 效果: 
# 將*SNAPSHOT.jar 的jar包copy到 BOOT-INF/lib目錄
# 將 *.properties 的 properties文件copy到BOOT-INF/classes目錄
# 將 *.yml 的 yml文件copy到BOOT-INF/classes目錄
# 將 *.xml 的 xml文件copy到BOOT-INF/classes目錄
# 將 BOOT-INF 壓縮到jar包內.
# 刪除臨時包, 並重啟, 列印當前日期


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景 昨天,一位朋友找到我尋求幫助。他的項目需要調用一個第三方項目的webAPI。這個webAPI本身可從header, query string中取相關信息,但同事發現他在調用時,無法按期望的那樣從query string中傳參數給到第三方webAPI (webAPI仿佛忽略了從query str ...
  • 在預設情況下,WPF提供的DataGrid僅擁有數據展示等簡單功能,如果要實現像Excel一樣複雜的篩選過濾功能,則相對比較麻煩。本文以一個簡單的小例子,簡述如何通過WPF實話DataGrid的篩選功能,僅供學習分享使用,如有不足之處,還請指正。 ...
  • Avalonia 實現平滑拖動指定控制項 1.創建一個UserControl控制項,並且添加以下代碼 using System; using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xa ...
  • 1. 問題:安裝 Microsoft.Toolkit.Mvvm 運行後報錯:錯誤 CS0012 類型“Object”在未引用的程式集中定義。必須添加對程式集“netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffc ...
  • 4. 容器中的服務創建與釋放 我們使用了 IoC 容器之後,服務實例的創建和銷毀的工作就交給了容器去處理,前面也講到了服務的生命周期,那三種生命周期中對象的創建和銷毀分別在什麼時候呢。以下麵的例子演示以下: 首先是新增三個類,用於註冊三種不同的生命周期: public class Service1 ...
  • ed中的替換命令s是 [address]s/pattern/replacement/flag sed和awk 都是面向字元流的。都是從文本文件中一次一行地讀取輸入 它們控制所做的工作時 所用的指令不同 sed的字元流定位對如何應用定址有重要影響。在ed中沒有指定地址的命令 隻影響當前行。sed遍歷文 ...
  • 前言 本文通過幾個簡單的示例,可以快速瞭解Makefile的基本使用方法,適用於編譯我們平時練習所編寫的小量代碼。 1. make命令 Makefile文件內容: all為目標,這裡沒有依賴的文件,這條命令是列印(echo)出“Hello Makefile”這行文字 all: echo "Hello ...
  • 安裝 WSL 2 查看可同時線上安裝的 Linux 發行版名稱 wsl -l -o # 或 wsl --list --online 安裝 WSL 2 命令 wsl --install # 此選項必需,以下選項按需選擇 --no-distribution # 且不安裝發行版 --distributio ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...