1. 程式人生 > >Shell筆記1——變量核心知識

Shell筆記1——變量核心知識

linux 運維 linux運維工程師

本文檔主要講解Shell變量的核心基礎知識與實踐

基本大綱:

1.Shell變量的分類

2.Shell中特殊且重要的變量

3.bash Shell 內置變量命令詳解

4.Shell變量子串知識及實踐

5.Shell特殊擴展變量的知識與實踐



一:變量可分為兩類:環境變量(全局變量)和普通變量(局部變量)。

變量概念:簡單地說、變量就是用一個固定的字符串(也可能是字符,數字等的組合)代替更多、更復雜的內容,該內容裏可能還會包含變量、路徑、字符串等其他的內容。

1)環境變量:也可稱為全局變量,可以在創建它們的Shell及其派生出來的任意子進程Shell中使用,環境變量又可分為自定義環境變量和bash內置的環境變量。(系統規範,所有的環境變量名字均采用大寫形式)

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,防止異常









Shell筆記1——變量核心知識