將本身以前的shell腳本筆記搬到segmentfault,順帶複習一下shell基礎。筆記大可能是讀<<跟老男孩學Linux運維:Shell編程實站>>時所記錄,推薦想學shell的能夠去看看。2019-1-26
系列筆記傳送門:linux
Shell介紹
Shell是一個命令解釋器,做用是解釋執行用戶輸入的命令程序等,用戶每輸入一條命令,Shell就執行解釋一條。這種從鍵盤輸入命令就能夠獲得迴應的方式叫作交互的方式。git
Shell存在於操做系統的最外層,負責與用戶直接對話,把用戶的輸入解釋給操做系統,並處理各類操做系統的輸出結果,而後輸出到屏幕給用戶。shell
Shell腳本
當命令或程序語句不在命令行下執行,而是經過一個程序文件來執行,這個文件就叫作Shell腳本。
Shell腳本很適合用於處理純文本類型的數據,而Linux系統中幾乎全部的配置文件,日誌文件(NFS,Rsync,Httpd,Nginx,LVS 等),以及絕大多數的啓動文件都是純文本類型的文件。所以,學好shell語言,就能夠利用它在linux系統中發揮巨大的做業。編程
查看CentOS系統默認的Shellvim
[root@moli_linux1 ~]# echo $SHELL /bin/bash [root@moli_linux1 ~]# grep root /etc/passwd root:x:0:0:root:/root:/bin/bash
Shell腳本的建立
一個規範的Shell腳本在第一行會指出由那個程序(解釋器)來執行腳本的內容,這一行內容在Linux bash編程中通常爲:segmentfault
#!/bin/bash
或者bash
#!/bin/sh
注意:這一行必須位於每一個腳本頂端的第一行,若是不是第一行則爲腳本註釋行。且shell腳本文件的後綴名一般以.sh
結尾。服務器
Shell腳本的執行
運維
1. bash script-name
(腳本的路徑名字)或者sh script-name
:這是當腳本文件沒有可執行權限時經常使用的放法
2. path/script-name
或者./script-name
:指在當前路徑下執行腳本(腳本須要有可執行權限)。即須要將腳本文件的權限先修改成可執行,chmod +xscript-name
。而後經過腳本的絕對路徑和相對路徑就能夠直接執行腳本。函數
什麼是變量
變量是暫時存儲數據的地方及數據標記,所存儲的數據存在於內存空間中,經過正確地調用內存空間中變量的名字就能夠取出與變量對應的數據。CentOS中變量的定義直接由一個賦值符號=
就能夠建立一個變量,而echo
命令相似於其餘語言的print
命令,打印這個變量的值。
[root@moli_linux1 ~] name="laowan" #定義一個變量 [root@moli_linux1 ~] echo $name #打印這個變量的值 laowan [root@moli_linux1 ~] age=14 [root@moli_linux1 ~] echo $age 14
shell變量的特性默認狀況下,在bash shell 中是不會區分變量類型的。
變量類型
變量分爲:環境變量(全局變量)和普通變量(局部變量)
環境變量能夠在建立它們的shell以及其派生出來的任意子進程shell中使用。環境變量又分爲自定義環境變量和bash內置的環境變量。
普通變量只能在建立它們的shell函數或shell腳本中使用。
提示:有三個命令能夠查看系統中變量的值:set、env、declare。
環境變量的定義
上面定義一個變量是在一個shell中直接使用賦值符號對這個變量進行建立,可是當打開一個新的子shell,打印這個變量卻不能打印出來。這是由於咱們建立的變量是一個普通變量,若想在其餘子shell中使用這個變量,須要將這個變量設置爲全局變量。而定義一個全局變量的方法以下:
export 變量名=value 或者 declare -x 變量名=value
第二個方法是將變量名添加到環境變量文件/etc/profile
編輯環境配置文件 vim /etc/profile 在文件最後面添加 export name="laowan" 保存,退出。從新加載文件 source /etc/profile 打印變量的值 echo $name laowan
而CentOS中,全局環境變量的配置文件有三個,分別是:
當用戶登陸Linux系統時,首先會先加載/etc/profile全局環境變量文件,這是Linux系統默認的Shell主配置文件,其次會執行/etc/profile.d下的腳本文件,要作重啓Linux系統後初始化或者顯示某些內容,只須要把腳本文件放在/etc/progile.d下便可,最後纔會執行bashrc文件。
設置登陸提示符
Linux中能夠設置登陸以後,或者遠程鏈接服務器打開的shell中顯示登陸提示符。設置登陸提示內容的文件是/etc/motd,編輯這個文件就能夠設置每次登陸提示的內容。例如:
[root@moli_linux1 ~]# cat /etc/motd welcome to my Linux Server! 打開一個新的shell Connecting to 192.168.30.3:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'. WARNING! The remote SSH server rejected X11 forwarding request. Last login: Sat Jan 26 19:35:54 2019 from 192.168.30.1 welcome to my Linux Server!
能夠看到登陸提示符。
定義變量不加單引號和雙引號,加單引號,加雙引號的區別
[root@moli_linux1 ~] a=10 [root@moli_linux1 ~] b=10-$a [root@moli_linux1 ~] c='100-$a' [root@moli_linux1 ~] d="100-$a" [root@moli_linux1 ~] echo $a 10 [root@moli_linux1 ~] echo $b 10-10 [root@moli_linux1 ~] echo $c 100-$a [root@moli_linux1 ~] echo $d 100-10
第一種定義b變量的方式,當內容爲簡單連續的數字,字符串,路徑名時,能夠這樣用,不加引號時,值裏有變量的會被解析後輸出。
第二種定義c的變量有加單引號,這樣輸出變量時單引號裏面內容是什麼就是什麼,即便有變量和命令也是直接輸出。
第三種定義d變量的方式加了雙引號,這種輸出變量內容時引號裏的變量以及命令會通過解析後再輸出內容,這種方式比較適合字符串中附帶有變量以及命令且想將其解析後再輸出的變量定義。
取消變量
取消變量使用unset命令,注意要取消的變量以前不用添加$
符號。
[root@moli_linux1 ~] a=100 [root@moli_linux1 ~] echo $a 100 [root@moli_linux1 ~] unset a [root@moli_linux1 ~] echo $a #能夠看到這個變量的爲空 [root@moli_linux1 ~]#
將一個命令的結果賦值給一個新的變量
生產環境中把命令的結果做爲變量的內容進行賦值的方法在腳本開發時很常見。有兩個方法能夠實現。
變量名=$(命令) 或者: 變量名=`命令` [root@moli_linux1 ~] ls 192.168.229 anaconda-ks.cfg git_data server shell-100 test-find [root@moli_linux1 ~] file=$(ls) [root@moli_linux1 ~] echo $file 192.168.229 anaconda-ks.cfg git_data server shell-100 test-find [root@moli_linux1 ~] file2=`ls` [root@moli_linux1 ~] echo $file2 192.168.229 anaconda-ks.cfg git_data server shell-100 test-find
shell中特殊位置參數變量
要從命令行,函數或腳本執行等處傳遞參數時,就要在shell腳本中使用位置參數變量。
示例1,特殊位置變量$1
[root@moli_linux1 script] cat test.sh #!/bin/bash echo $1 #腳本的功能是打印腳本傳遞的第一個參數的值 [root@moli_linux1 script] sh test.sh laowan #傳入一個字符串參數,賦值給$1 laowan [root@moli_linux1 script] sh test.sh laowan xiaoming #傳入多個參數,但腳本不會接收多個參數,所以只輸出第一個參數的值 laowan [root@moli_linux1 script] sh test.sh "I am laowan" #用雙引號括起來表明一個參數 I am laowan
示例2,特殊位置變量$1,$2,$3....${10}
[root@moli_linux1 script] echo \${1..15} > test2.sh [root@moli_linux1 script] cat test2.sh #!/bin/bash echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 [root@moli_linux1 script] sh test2.sh {a..z} #傳入26個字母a~z,做爲26個參數 a b c d e f g h i a0 a1 a2 a3 a4 a5 #位置參數的數字大於9後,輸出內容就不對了 [root@moli_linux1 script] vim test2.sh [root@moli_linux1 script] cat test2.sh #!/bin/bash #位置參數的數字大於9時,須要用大括號將數字括起來 echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} [root@moli_linux1 script] sh test2.sh {a..z} a b c d e f g h i j k l m n o #大於9的數字加上大括號後顯示正確的內容
示例3,特殊變量$0--獲取腳本的名稱以及路徑:
[root@moli_linux1 shell_test] cat 05-getName.sh #!/bin/bash echo $0 [root@moli_linux1 shell_test] sh 05-getName.sh 05-getName.sh
示例4,$#獲取腳本傳遞參數個數:
[root@moli_linux1 shell_test] cat 06-getNum.sh #!/bin/bash echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 echo $# #傳遞的參數個數 [root@moli_linux1 shell_test] ./06-getNum.sh {a..z} #傳遞了26個字母,即26個參數 ./06-getNum.sh a b c d e f g h i #接受了9個參數,所以打印9個字母 26 #傳遞了26個參數,打印出26
示例5,$#的常見實際應用
根據用戶在命令行傳參的個數判斷用戶的輸入,不符合的給出提示並退出,符合的打印出傳入的參數內容。
[root@moli_linux1 shell_test] cat t1.sh #!/bin/bash if [ $# -ne 2 ] #若是執行腳本傳參的個數不等於2 then echo "USAGE:/bin/sh $0 arg1 arg2" #則給用戶提示正確的用法,此處$0,打印腳本名字和路徑 exit 1 #不滿要求,則退出腳本,返回值爲1 fi echo $1 $2 #符合要求,則打印$1 $2所獲取到的傳參的字符串 [root@moli_linux1 shell_test] sh t1.sh arg1 agr2 #符合傳參個數=2,打印出傳入參數的內容 arg1 agr2 [root@moli_linux1 shell_test] sh t1.sh arg1 agr2 arg3 #不符合傳參個數=2,給出提示並退出 USAGE:/bin/sh t1.sh arg1 arg2
上一個指令
的執行狀態返回值(0爲成功,非0爲失敗),這個變量最經常使用。$?
的實踐1
[root@moli_linux1 ~] pwd #執行pwd獲取當前路徑,用echo $?查看執行命令的狀態返回值 /root [root@moli_linux1 ~] echo $? 0 #返回0表示上一條命令執行成功 [root@moli_linux1 ~] rm shell_test/ #刪除目錄shell_test rm: 沒法刪除"shell_test/": 是一個目錄 #沒加參數-r ,沒法刪除 [root@moli_linux1 ~] echo $? 1 #狀態碼非0,表示上一條執行不成功或者錯誤
$?
的實踐2
[root@moli_linux1 ~] cat test1.sh #!/bin/bash [ $# -ne 2 ] && { #若是參數個數不=2 echo "must be two args." #則輸出提示 exit 119 #終止程序並以指定的119狀態碼退出程序,賦值給當前shell的「$?」變量。 } echo "success!" [root@moli_linux1 ~]# sh test1.sh 1 2 3 #參數個數不=2 must be two args. [root@moli_linux1 ~]# echo $? 119 #狀態碼爲119
"$?"
的注意點:
變量字串表達式
表達式 | 說明 |
---|---|
${parameter} | 返回變量${parameter}的內容 |
${#parameter} | 返回變量${parameter}內容的長度(按字符) |
${parameter:offset} | 在變量${parameter}的內容中,從位置offset以後開始提取字串到結尾 |
${parameter:offset:length} | 在變量${parameter}中,從位置offset以後開始提取長度爲length的字串 |
${parameter#word} | 從變量${parameter}開頭 開始刪除最短 匹配的word字串 |
${parameter##word} | 從變量${parameter}開頭 開始刪除最長 匹配的word字串 |
${parameter%word} | 從變量${parameter}結尾 開始刪除最短 匹配的word字串 |
${parameter%%word} | 從變量${parameter}結尾 開始刪除最短 匹配的word字串 |
${parameter/pattern/string} | 使用string替換第一個 匹配的pattern |
${parameter//pattern/string} | 使用string替換全部 匹配的pattern |
#
」:表示從開頭刪除最短匹配##
」:表示從開頭刪除最長匹配%
」:表示從結尾開始刪除最短匹配%%
」:表示從結尾開始刪除最長匹配/
」:表示替換第一個//
」:表示替換全部示例1,變量的打印和提取切片:
# 定義變量parameter,內容爲abc123ABC456 [root@moli_linux1 script]# parameter="abc123ABC456" # 變量的兩種打印方式 [root@moli_linux1 script]# echo $parameter abc123ABC456 [root@moli_linux1 script]# echo ${parameter} abc123ABC456 # 打印這個變量內容的長度,一共12個字符 [root@moli_linux1 script]# echo ${#parameter} 12 # 從變量內容的第三個開始,提取剩下的全部內容 [root@moli_linux1 script]# echo ${parameter:3} 123ABC456 # 從變量內容的第三個開始,提取接下來的6個字符 [root@moli_linux1 script]# echo ${parameter:3:6} 123ABC
示例2,變量的截取與替換:
# 定義變量,mori [root@moli_linux1 script]# echo $mori abc123ABC456abc # 從開頭刪除了最短的a*c字串爲abc [root@moli_linux1 script]# echo ${mori#a*c} 123ABC456abc # 從開頭刪除了最長的a*c字串爲abc123ABC456abc,所有刪除了 [root@moli_linux1 script]# echo ${mori##a*c} [root@moli_linux1 script]# # 從左到右將第一個遇到的小寫a替換爲大寫A [root@moli_linux1 script]# echo ${mori/a/A} Abc123ABC456abc # 將變量裏全部的小寫a替換爲大寫A [root@moli_linux1 script]# echo ${mori//a/A} Abc123ABC456Abc