shell 腳本簡單概括和實踐

閱讀原文java

if 條件 OPTION

OPTION 解釋
[-a file] 若是file存在則爲真 ,也能夠表示爲 and: 條件與
if [ -z "condition1" -a -z "condition2" ]
[-b file] 若是file存在且是一個特殊文件則爲真
[-c file] 若是file存在且是一個特殊文件則爲真
[-d file] 若是 file 文件存在且是一個目錄則爲真,d前的!是邏輯非 
#表示目錄不存在,則執行後面的 then 操做 
if [ ! -d lcd_path/par_date ]
[-e file] 若是 file文件存在則爲真
[-f file] 若是 file 存在且是一個普通文件則爲真
[-g file] 若是 file 存在且已經設置了SGID則爲真(SUID 是 Set User ID, SGID 是 Set Group ID的意思)
[-h file] 若是 file 存在且是一個符號鏈接則爲真
[-k file] 若是 file 存在且已經設置粘制位則爲真
[-p file] 若是file存在且是一個名字管道(F若是O)則爲真。管道是linux裏面進程間通訊的一種方式,
其餘的還有像信號(signal)、信號量、消息隊列、共享內存、套接字(socket)等
[-r file] 若是file存在且是可讀的則爲真
[-s file] 若是file存在且大小不爲0則爲真
[-t FD] 若是文件描述符FD打開且指向一個終端則爲真
[-u file] 若是file存在且設置了SUID(set userID)則爲真
[-w file 若是file存在且是可寫的則爲真
[-x file] 若是file存在且是可執行的則爲真
[-O file] 若是file存在且屬有效用戶ID則爲真
[-G file] 若是file存在且屬有效用戶組則爲真
[-L file] 若是file存在且是一個符號鏈接則爲真
[-N file] 若是file存在and has been mod若是ied since it was last read則爲真
[-S file] 若是file存在且是一個套接字則爲真
[-o optionname] 若是shell選項「optionname」開啓則爲真
[-z string] 「string」的長度爲零則爲真
[-n string] or [string] 「string」的長度爲非零non-zero則爲真

if 基本判斷

  • [file1 –nt file2] 若是file1 has been changed more recently than file2或者file1 exists and file2 does not則爲真
  • [file1 –ot file2] 若是file1比file2要老,或者file2存在且file1不存在則爲真
  • [file1 –ef file2] 若是file1和file2指向相同的設備和節點號則爲真
  • [sting1==string2] 若是2個字符串相同。「=」may be used instead of 「==」for strict posix compliance則爲真
  • [string1!=string2] 若是字符串不相等則爲真
  • [string1<string2] 若是「string1」sorts before「string2」lexicographically in the current locale則爲真
  • [arg1 OP arg2]  「OP」is one of –eq,-ne,-lt,-le,-gt or –ge

截取字符串

  • # 號截取,刪除左邊字符,保留右邊字符。 (非貪婪匹配)
var=http://www.glmapper.com
# # 號是運算符,*/ 表示從左邊開始刪除第一個 / 號及左邊的全部字符,即刪除 http://
echo ${var#*//}
#結果 www.glmapper.com
複製代碼
  • ## 號截取,刪除左邊字符,保留右邊字符。(貪婪匹配)****
var=http://www.glmapper.com
# ##*/ 表示從左邊開始刪除最後(最右邊)一個 / 號及左邊的全部字符
echo ${var##*//}

# 結果 www.glmapper.com
複製代碼
  • %號截取,刪除右邊字符,保留左邊字符 (非貪婪匹配)
var=http://www.glmapper.com
# %/* 表示從右邊開始,刪除第一個 / 號及右邊的字符
echo ${var%/*}
# 結果是:http:/
複製代碼
  • %% 號截取,刪除右邊字符,保留左邊字符  (貪婪匹配)
var=http://www.glmapper.com
# %%/* 表示從右邊開始,刪除最後(最左邊)一個 / 號及右邊的字符
echo ${var%%/*}
# 結果 :http: 
複製代碼
  • 從左邊第幾個字符開始,及字符的個數
var=http://www.glmapper.com
# 其中的 0 表示左邊第一個字符開始,5 表示字符的總個數
echo ${var:0:5}
# 結果 http:
複製代碼
  • 從左邊第幾個字符開始,一直到結束
var=http://www.glmapper.com
# 其中的 7 表示左邊第8個字符開始,一直到結束。
echo ${var:7}
# 結果 www.glmapper.com
複製代碼
  • 從右邊第幾個字符開始,及字符的個數
var=http://www.glmapper.com
# 其中的 0-3 表示右邊算起第3個字符開始,3 表示字符的個數
echo ${var:0-3:3}
# 結果 com
複製代碼
  • 從右邊第幾個字符開始,一直到結束
var=http://www.glmapper.com
# 表示從右邊第 3 個字符開始,一直到結束
echo ${var:0-3}
# 結果 com
複製代碼

左邊的第一個字符是用 0 表示,右邊的第一個字符用 0-1 表示linux

basename

basename 命令簡介

去除文件名的目錄部分和後綴部分。basename 命令讀取 String 參數,刪除以 /(斜槓) 結尾的前綴以及任何指定的 Suffix 參數,並將剩餘的基本文件名稱寫至標準輸出。basename 和 dirname 命令一般用於 shell 腳本中的命令替換來指定和指定的輸入文件名稱有所差別的輸出文件名稱。
**
基本語法以下:shell

basename NAME [SUFFIX]
basename OPTION
複製代碼

基本示例

basename /usr/bin/sort
# 返回 sort

basename /usr/bin/sort/glmapper.txt
# 返回 glmapper.txt
複製代碼

建立基本文件名稱的規則

  • 若是 String 參數是 //(雙斜槓) 或若是 String 參數包含的都是斜槓字符,則將字符串更改成單個 /(斜槓)
basename //usr//bin//sort//glmapper.txt
# 返回 glmapper.txt

basename ////
# 返回 /
複製代碼
  • 從指定字符串除去任何拖尾的 / 字符。
basename /usr/bin/sort/
# 返回 sort
複製代碼
  • 若是在 String 參數中剩餘任何 / 字符,則除去字符串的前綴直到(包含)最後一個 / 字符。
  • 若是指定 Suffix 參數,且它和字符串中的剩餘的字符相同,則不修改此字符串
basename /usr/bin/sort/glmapper.txt glmapper.txt 
# 返回glmapper.txt 

basename /usr/bin/sort/glmapper.txt .txt 
# 返回 glmapper
複製代碼

shell 查看當前目錄下文件的個數

測試準備,test 目錄下有 test一、test2 兩個文件夾和一個 1.txt 文件。bash

-test
├── 1.txt
├── test1
│   └── test1_1.txt
└── test2
複製代碼
  • 查看當前目錄下文件的個數
test ls -l | grep "^-" | wc -l
   1 # 1.txt
複製代碼
  • 查看當前目錄下文件的個數,包括子目錄裏的
test ls -lR| grep "^-" | wc -l
   2 # 1.txt test1_1.txt
複製代碼
  • 查看某目錄下文件夾(目錄)的個數,包括子目錄裏的
test ls -lR| grep "^d" | wc -l
	 2 # test1 test2
複製代碼
  • 說明:
一、ls -l :長列表輸出該目錄下文件信息(注意這裏的文件,不一樣於通常的文件,多是目錄、連接、設備文件等)
二、grep "^-" :這裏將長列表輸出信息過濾一部分,只保留通常文件,若是隻保留目錄就是 ^d
三、wc -l : 統計輸出信息的行數,已通過濾得只剩通常文件了,統計結果就是通常文件信息的行數,
					又一行信息對應一個文件,也就是文件的個數
複製代碼

利用簡單的命令組合實現配置文件的獲取

測試準備,在 1.txt 中 增長兩個屬性:app

name=glmapper
age=26
複製代碼
cat /Users/guolei/logs/test/1.txt | sed 's|[[:blank:]]||g' | grep "^name=" | cut -d= -f2
# 返回 glmapper 

cat /Users/guolei/logs/test/1.txt | sed 's|[[:blank:]]||g' | grep "^age=" | cut -d= -f2
# 返回 26
複製代碼

函數封裝與返回

以上面的解析配置文件爲例,將其封裝成一個函數socket

function load_param()
{
    # 接受的第一個參數是文件地址
    local properties_file=$1
    # 接受的第二個參數是屬性名
    local param=$2
    RESULT=`cat $properties_file | sed 's|[[:blank:]]||g' | grep "^$param=" | cut -d= -f2`
}
複製代碼

調用函數而且獲取返回值函數

load_param 1.txt name
PROP_VAL=$RESULT
echo $PROP_VAL
# 返回 glmapper
複製代碼

shell 實現日誌文件的歸檔處理

日誌歸檔簡單來講就是,每次但願啓動,會將前一次程序運行產生的日誌和本地運行產生的日誌隔離開來,歸檔結果就是產生相似於以下的日誌文件:測試

  • stdout.log.20170909
  • stdout.log.20170709
  • stdout

因此日誌文件的歸檔在生產腳本中是必需要考慮的,不然就到致使每次產生的文件都會被寫入同一份日誌文件中。下面是實踐過程當中概括的一個日誌歸檔函數:ui

# archive log
function archive_log() {
    local FILE_STDOUT_LOG=$LOG_ROOT/stdout.log
    local FILE_STDERR_LOG=$LOG_ROOT/stderr.log
    if [ ! -e $LOG_ROOT ] ; then
        mkdir -p $LOG_ROOT
    fi
    NOW=`date +%Y%m%d.%H%M%S`
    # scroll SOFABoot STDOUT log
    if [ -e $FILE_STDOUT_LOG ] ; then
        mv $FILE_STDOUT_LOG $FILE_STDOUT_LOG.$NOW
    fi

    # scroll SOFABoot STDERR log
    if [ -e $FILE_STDERR_LOG ] ; then
        mv $FILE_STDERR_LOG $FILE_STDERR_LOG.$NOW
    fi

    FILE_STDOUT_LOG_GLOBAL=$FILE_STDOUT_LOG;
    FILE_STDERR_LOG_GLOBAL=$FILE_STDERR_LOG;
}
複製代碼

一個簡單的 SOFABoot 啓動腳本

deploy.sh  簡單的啓動腳本:spa

LOG_ROOT= $1;
APP_PATH= $2;
# 檢查 JAVA_HOME
if [ -z "$JAVA_HOME" ]; then
  echo "JAVA_HOME not set, exit"
  exit 1
fi
# 使用前面的那個日誌歸檔函數
archive_log

# 啓動 java 程序
java -jar $APP_PATH >> $FILE_STDOUT_LOG_GLOBAL 2>> $FILE_STDOUT_LOG_GLOBAL &
複製代碼

運行:

sh deploy.sh ./logs app.jar 
複製代碼

小結

本文記錄平常中常遇到的 shell 命令,基礎知識部分零碎的參考了網上一些同窗的博客,在此作了概括。也歡迎你們指正。若是你有比較騷氣的操做,也歡迎評論席留言,我會驗證後更新到文章中來。

相關文章
相關標籤/搜索