本文檔主要講解Shell變量的核心基礎知識與實踐
shell
基本大綱:bash
1.Shell變量的分類
ssh
2.Shell中特殊且重要的變量ide
3.bash Shell 內置變量命令詳解函數
4.Shell變量子串知識及實踐this
5.Shell特殊擴展變量的知識與實踐spa
一:變量可分爲兩類:環境變量(全局變量)和普通變量(局部變量)。orm
變量概念:簡單地說、變量就是用一個固定的字符串(也多是字符,數字等的組合)代替更多、更復雜的內容,該內容裏可能還會包含變量、路徑、字符串等其餘的內容。進程
1)環境變量:也可稱爲全局變量,能夠在建立它們的Shell及其派生出來的任意子進程Shell中使用,環境變量又可分爲自定義環境變量和bash內置的環境變量。(系統規範,全部的環境變量名字均採用大寫形式)ip
1.設置環境變量,三種方法
①export 變量名=value
②變量名=value;export 變量名
③declare -x 變量名=value
2.用戶的環境變量配置
/root/.bashrc
/root/.bash_profile
小結:對於用戶的環境變量設置,比較常見的是用戶家目錄下的.bashrc和.bash_profile這兩個文件
3. 全局環境變量的配置文件以下:
/etc/profile
/etc/bashrc
/etc/profile.d/
如果在登陸後初始化或顯示加載內容,則把腳本文件放在/etc/profile.d/下便可(無須加執行權限)
4.定義環境變量的經驗小結:
①變量名一般要大寫
②經常使用export來定義環境變量
③用env和set顯示默認的環境變量,用unset消除本地變量和環境變量。
④書寫crond定時任務時要注意,腳本要用到的環境變量最好先在所執行的Shell腳本中從新定義。
⑤若是但願環境變量永久生效,則能夠將其放在用戶環境變量文件或全局環境變量文件裏。
2)普通變量:也可稱爲局部變量,只能在建立它們的Shell函數或Shell腳本中使用。普通變量通常由開發者在開發腳本程序時建立。
1.設置普通變量,三種方法
①變量名=value #此方法適合定義簡單的數字,字符串,以及路徑名
②變量名='value' #此方法適合定義顯示純字符串,不解析變量,以及命令的場景
③變量名="value" #此方法適合定義字符串中帶有變量及命令,須要解析出來再輸出的變量定義。定義變量加引號是最多見的使用場景
定義變量經驗:
數字內容的變量定義能夠不加引號,其餘沒有特殊要求的字符串等定義最好都加上雙引號,若是真的須要原樣輸出就加單引號,定義變量加雙引號是最多見的使用場景。
2.把一個命令的結果做爲變量的內容賦值,兩種方法
①變量名=`ls`
②變量名=$(ls) #推薦使用此法
生產場景中把命令的結果作爲變量的內容進行賦值的方法在腳本開發時很常見
3.局部(普通)變量定義及賦值經驗小結:
①若變量內容爲連續的數字或字符串,賦值時,變量內容兩邊能夠不加引號。例如:a=123,abc
②變量的內容不少時,若是有空格且但願解析內容中的變量,就加雙引號。例如a="abc $USER",此時輸出變量會對內容中的$USER進行解析而後再輸出
③但願原樣輸出變量中的內容就用單引號引發內容進行賦值,例如:a='$USER' ,那麼echo $a —> $USER
④命令的解析結果定義與賦值,要使用反引號將賦值的命令括起來,例如:a=`ls` ;或者用$()括起來,例如:a=$(ls)
⑤變量的輸出方法:使用「$變量名」便可輸出變量的內容,經常使用「echo $變量名」的方式,也能夠用printf代替echo輸出更復雜的格式內容
⑥用echo等命令輸出變量的時候,也可用單引號、雙引號、反引號,例如:echo $A 、echo '$A'、echo "$A",它們的用法和前面變量內容定義的總結是一致的。
⑦$dbname_tname,當變量後面鏈接有其餘字符的時候,必須給變量名加上大括號{},例如:$dbname_tname改爲${dbname}_tname
#注:這些結論僅針對Linux Shell,sed和grep是一致的,只是對於awk語言有些特別
awk結論:
awk加單引號後再同時加雙引號能保證都是正確輸出。無論變量如何定義,賦值,除了加單引號外,利用awk直接獲取變量的輸出,結果都是同樣的。所以,在awk取用shell變量時,咱們更多地仍是喜歡先用echo加符號輸出變量,而後經過管道給awk,進而控制變量的輸出結果。例如:echo $USER|awk '{print $0}'
二:Shell中特殊且重要的變量
1)Shell中的特殊位置參數變量
$0 #獲取當前執行的shell腳本的文件名,若是執行腳本包含了路徑,那麼就包含了路徑,那麼就包括腳本路徑
$n #獲取當前執行的Shell腳本的第n個參數值,n=1..9,當n爲0時表示腳本的文件名;若是n大於9,則用大括號括起來,例如${10},接的參數一空格隔開
$# #獲取當前執行的shell腳本後面接的參數的總個數
$* #獲取當前shell腳本全部傳參的參數,不加引號和$@相同;若是給$@加上雙引號,例如:「$*」,則表示將全部的參數視爲單個字符串,至關於「$1 $2 $3」
$@ #獲取當前shell腳本全部傳參的參數,不加引號和$*相同;若是給$@加上雙引號,例如:「$@」,則表示將全部的參數視爲不一樣的獨立字符串,至關於"$1""$2""$3""..."。這是將多參數傳遞給其它程序的最佳方式,由於它保留全部的內嵌在每一個參數裏的任何空白。當"$@"和"$*"都加雙引號時,二者是有區別的;都不加雙引號時,二者無區別
2)Shell進程中的特殊狀態變量
$? #獲取執行上一個指令的執行狀態返回值(0爲成功,非零爲失敗),這個很經常使用
$$ #獲取當前執行的Shell腳本的進程號(PID),這個變量不經常使用
$! #獲取上一行在後臺工做的進程的進程號(PID),這個變量不經常使用
$_ #獲取在此以前執行的命令或腳本的最後一個參數,這個變量不經常使用
注:$?:不一樣命令的執行結果中,$?的返回值不盡相同,但在工做場景中,經常使用的就是0和非0狀態,0表示成功,非0表示運行失敗或者未成功
三:bash Shell 內置變量命令詳解
1.echo命令參數選項詳解 :
-n #不換行輸出內容 -e #解析轉義字符(見下面的字符)
\n #換行 \r #回車 \t #製表符 \b #退格 \v #縱向製表符
#注:printf和echo -e的轉義字符能力類似
2.eval
命令格式:eval args
功能:當shell程序執行到eval語句時,Shell讀入參數agrs,並將它們組合成一個新的命令,而後執行
[root@localhost practice]# cat noeval.sh
echo \$$#
[root@localhost practice]# sh noeval.sh 2 1
$2
[root@localhost practice]# cat noeval.sh
eval "echo \$$#" #傳入兩個參數,$#爲2,echo \$$#變爲echo $2,再加上eval命令,使得$2從新解析輸出,而不是自己。因此下面輸出了2
[root@localhost practice]# sh noeval.sh 1 2
2
3.exec
命令格式:exec命令參數
功能:exec命令可以在不建立新的子進程的前提下,轉去執行指定的命令,當指定的命令執行完畢後,該進程(也就是最初的Shell)就終止了,示例以下:
[root@localhost practice]# cat /tmp/tmp.log
1
2
[root@localhost practice]# cat exec.sh
exec < /tmp/tmp.log #讀取log內容
while read line #利用read一行行讀取處理
do
echo $line
done
echo OK
[root@localhost practice]# sh exec.sh
1
2
OK
4.read
命令格式:read變量名錶
功能:從標準輸入讀取字符串等信息,傳給shell程序內部定義的變量。
read -p "屏幕打印字符串:" a
echo $a #從屏幕打印輸出賦值給腳本變量使用
5.shift
命令格式:shift-Shift positional parameters
功能:shift語句會按以下方式從新命名全部的位置參數變量,即$2成爲$1,$3成爲$2等,以此類推 做用:很方便
[root@localhost practice]# set -- "1" "2"
[root@localhost practice]# shift
[root@localhost practice]# echo $1
2
shift生產環境案例:
[root@localhost practice]# sed 8,25p /usr/bin/ssh-copy-id -n
ID_FILE="${HOME}/.ssh/id_rsa.pub"
if [ "-i" = "$1" ]; then
shift
# check if we have 2 parameters left, if so the first is the new ID file
if [ -n "$2" ]; then
if expr "$1" : ".*\.pub" > /dev/null ; then
ID_FILE="$1"
else
ID_FILE="$1.pub"
fi
shift # and this should leave $1 as the target name
fi
else
if [ x$SSH_AUTH_SOCK != x ] ; then
GET_ID="$GET_ID ssh-add -L"
fi
fi
6.exit
命令格式:exit-Exit the shell
功能:退出shell程序。在exit以後能夠有選擇地指定一個數位做爲返回狀態。
四:Shell變量子串知識及實踐
1)變量子串介紹
①${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
2)變量子串實踐
1).${parameter} #返回變量$parameter的內容
示例:
[root@aliyun dcindex]# ywxi="I am ywxi"
[root@aliyun dcindex]# echo ${ywxi}
I am ywxi
2).${#parameter} #返回變量$parameter內容的長度(按字符),也適用於特殊變量
示例:
[root@aliyun dcindex]# echo ${#ywxi}
9
[root@aliyun dcindex]# echo $ywxi|wc -L
9
[root@aliyun dcindex]# expr length "$ywxi"
9
[root@localhost ~]# echo $ywxi|awk '{print length'"$0"'}'
9
3).${parameter:offset) #在變量${parameter}中,從位置offset以後開始提取子串到結尾
示例:
[root@localhost practice]# echo ${ywxi}
I am ywxi
[root@localhost practice]# echo ${ywxi:2}
am ywxi
4).${parameter:offset:length} #在變量${parameter}中,從位置offset以後開始提取長度爲length的字串
示例:
[root@localhost practice]# echo ${ywxi}
I am ywxi
[root@localhost practice]# echo ${ywxi:2:2}
am
等價於
[root@localhost practice]# echo ${ywxi}|cut -c 3-4
am
5).${parameter#word} #從變量${parameter}開頭開始刪除最短匹配的word子串
示例:
[root@localhost practice]# ywxi=abcABC123ABCabc
[root@localhost practice]# echo ${ywxi#a*C}
123ABCabc
[root@localhost practice]# echo ${ywxi#a*c}
ABC123ABCabc
6).${parameter##word} #從變量${parameter}開頭開始刪除最長匹配的word子串
示例:
[root@localhost practice]# echo $ywxi
abcABC123ABCabc
[root@localhost practice]# echo ${ywxi##a*c}
[root@localhost practice]# echo ${ywxi##a*C}
abc
7).${parameter%word} #從變量${parameter}結尾開始刪除最短匹配的word子串
示例:
[root@localhost practice]# echo $ywxi
abcABC123ABCabc
[root@localhost practice]# echo ${ywxi%a*c}
abcABC123ABC
[root@localhost practice]# echo ${ywxi%a*C}
abcABC123ABCabc
8).${parameter%%word} #從變量${parameter}結尾開始刪除最長匹配的word子串
示例:
[root@localhost practice]# echo $ywxi
abcABC123ABCabc
[root@localhost practice]# echo ${ywxi%%a*c}
[root@localhost practice]# echo ${ywxi%%a*C}
abcABC123ABCabc
有關匹配刪除的小結:
#表示從開頭刪除匹配最短
##表示從開頭刪除匹配最長
%表示從結尾刪除匹配最短
%%表示從結尾刪除匹配最長
a*c表示匹配的字符串,*表示匹配全部,a*c匹配開頭爲a、中間爲任意多個字符、結尾爲c的字符串
a*C表示匹配的字符串,*表示匹配全部,a*c匹配開頭爲a、中間爲任意多個字符、結尾爲C的字符串
9).${parameter/pattern/string} #使用string代替第一個匹配的pattern
示例:
[root@localhost practice]# ywxi="I am oldboy,yes,oldboy"
[root@localhost practice]# echo $ywxi
I am oldboy,yes,oldboy
[root@localhost practice]# echo ${ywxi/oldboy/oldgirl}
I am oldgirl,yes,oldboy
10).${parameter//pattern/string} #使用string代替全部匹配的pattern
示例:
[root@localhost practice]# echo ${ywxi//oldboy/oldgirl}
I am oldgirl,yes,oldgirl
有關替換的小結:
#一個"/"表示替換匹配的第一個字符串
#兩個"/"表示替換匹配的全部字符串
五:Shell特殊擴展變量的知識與實踐
1)特殊擴展變量介紹
①${parameter:-word} #用途:若是變量未定義,則返回備用的值,防止變量爲空值或因未定義而致使異常
②${parameter:=word} #用途:基本同上一個${parameter:-word},但該變量又額外給parameter變量賦值了
③${parameter:?word} #用途:用於捕捉因爲變量未定義而致使的錯誤,並退出程序
④${parameter:+word} #若是parameter變量值爲空或未賦值,則什麼都不作,不然word字符串將替代變量的值
2)特殊擴展變量實踐
shell範例11:
1)${parameter:-word} #用途:若是變量未定義,則返回備用的值,防止變量爲空值或因未定義而致使異常
[root@localhost scripts]# echo $test
[root@localhost scripts]# result=${test:-UNSET}
[root@localhost scripts]# echo $result
UNSET
[root@localhost scripts]# echo $test
[root@localhost scripts]#
[root@localhost scripts]# test=oldboy
[root@localhost scripts]# echo $test
oldboy
[root@localhost scripts]# result=${test:-UNSET}
[root@localhost scripts]# echo $result
oldboy
[root@localhost scripts]# echo $test
oldboy
[root@localhost practice]# result=${test-UNSET}
[root@localhost practice]# echo $result
oldboy
2)${parameter:=word} #用途:基本同上一個${parameter:-word},但該變量又額外給parameter變量賦值了
[root@localhost practice]# result=${test:=UNSET}
[root@localhost practice]# echo $result
UNSET
[root@localhost practice]# echo $test
UNSET
[root@localhost practice]# result=${test=UNSET}
[root@localhost practice]# echo $result
UNSET
[root@localhost practice]# echo $test
UNSET
3)${parameter:?word} #用途:用於捕捉因爲變量未定義而致使的錯誤,並退出程序
[root@localhost practice]# echo ${key:?not defined}
-bash: key: not defined
[root@localhost practice]# key=1
[root@localhost practice]# echo ${key:?not defined}
1
[root@localhost practice]# echo ${key?not defined}
1
[root@localhost practice]# unset key
[root@localhost practice]# echo ${key:?not defined}
-bash: key: not defined
4)${parameter:+word} #若是parameter變量值爲空或未賦值,則什麼都不作,不然word字符串將替代變量的值
[root@localhost practice]# unset oldboy
[root@localhost practice]# unset oldgirl
[root@localhost practice]# oldboy=${oldgirl:+word}
[root@localhost practice]# echo $oldboy
[root@localhost practice]# oldgirl=19
[root@localhost practice]# oldboy=${oldgirl:+word}
[root@localhost practice]# echo $oldboy
word
http啓動服務示例:
[root@aliyun ~]# cat /etc/init.d/httpd
HTTPD_LANG=${HTTPD_LANG-"C"} #若是變量HTTPD_LANG未定義,則返回C,防止異常
httpd=${HTTPD-/usr/sbin/httpd} #若是HTTPD未定義,則返回/usr/sbin/httpd,防止異常
pidfile=${PIDFILE-/var/run/httpd/httpd.pid} #若是PIDFILE未定義,則返回/var/run/httpd/httpd.pid,防止異常
lockfile=${LOCKFILE-/var/lock/subsys/httpd} #若是LOCKFILE未定義,則返回/var/lock/subsys/httpd,防止異常