Shell編程之特殊變量和擴(kuò)展變量詳解
特殊變量
在Shell中的特殊變量主要分別兩種位置參數(shù)變量、狀態(tài)變量?jī)煞N。
位置參數(shù)變量
Shell中的位置參數(shù)變量主要是指0、0、1、$#等,主要用于從命令行、函數(shù)或腳本執(zhí)行等地方傳遞參數(shù)。詳細(xì)說明如下所示:
- $0:獲取當(dāng)前執(zhí)行的Shell腳本的文件名,如腳本中包含路徑,則輸出也包括路徑
- $n:獲取當(dāng)前執(zhí)行的Shell腳本的第n個(gè)參數(shù)值,如n>9,則需要使用用大括號(hào),如${10},各參數(shù)間用空格進(jìn)行分隔
- $#:獲取當(dāng)前執(zhí)行的Shell腳本傳入?yún)?shù)的總個(gè)數(shù)
- $*:獲取當(dāng)前執(zhí)行的Shell所有傳入?yún)?shù),如不加引號(hào)則與$@功能相同,如果添加雙引號(hào)**"∗",則表示將所有傳入?yún)?shù)視為單個(gè)字符串∗∗,相當(dāng)于"∗",則表示將所有傳入?yún)?shù)視為單個(gè)字符串∗∗,相當(dāng)于"1 223"
- $@:獲取當(dāng)前執(zhí)行的Shell所有傳入?yún)?shù),**如不加引號(hào)則與$*功能相同,如果添加雙引號(hào)"@",則表示將所有傳入?yún)?shù)視為獨(dú)立的字符串∗∗,相當(dāng)于"@",則表示將所有傳入?yún)?shù)視為獨(dú)立的字符串∗∗,相當(dāng)于"1" "2""2""3"
當(dāng)"∗"和"∗"和"@"都添加雙引號(hào)時(shí),兩者的功能有所區(qū)別;如不加,則功能相同,無區(qū)別。
位置參數(shù)變量示例
1、示例一:
[root@localhost Test]# cat para.sh #!/bin/bash echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} echo '$0 is:' $0 echo '$1 is:' $1 echo '$12 is:' ${12} echo '$# is:' $# echo '$* is:' $* echo '"$*"is:' "$*" echo '$@ is:' $@ echo '"$@"is:' "$@" # 輸出結(jié)果 [root@localhost Test]# bash ~/Test/para.sh {a..z} a b c d e f g h i j k l m n o $0 is: /root/Test/para.sh $1 is: a $12 is: l $# is: 26 $* is: a b c d e f g h i j k l m n o p q r s t u v w x y z "$*"is: a b c d e f g h i j k l m n o p q r s t u v w x y z $@ is: a b c d e f g h i j k l m n o p q r s t u v w x y z "$@"is: a b c d e f g h i j k l m n o p q r s t u v w x y z
1、傳入的參數(shù)個(gè)數(shù)多于腳本定義的參數(shù)時(shí),則多出的參數(shù)會(huì)忽略
2、傳入的參數(shù)中如使用雙引號(hào),則會(huì)當(dāng)作一個(gè)參數(shù)值進(jìn)行傳遞
3、位置參數(shù)如大于9,需要使用${}進(jìn)行傳遞
2、示例二:
[root@localhost Test]# cat testposition.sh #!/bin/bash echo '$# $1 $2 $3 $* $@' echo $# $1 $2 $3 $* $@ echo "************" echo '$*' for tmp in $* do echo $tmp done echo "************" echo "@@@@@@@@@@@@" echo '$@' for temp in $@ do echo $temp done echo "@@@@@@@@@@@@" echo '"*"*"*"*"*"*' echo '$*' for i in "$*" do echo $i done echo '"*"*"*"*"*"*' echo '"@"@"@"@"@"@' echo '$@' for j in "$@" do echo $j done echo '"@"@"@"@"@"@' [root@localhost Test]# bash testposition.sh "Hello Jack" Welcome "to Shanghai" $# $1 $2 $3 $* $@ 3 Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai ************ $* # 未加雙引號(hào),所以會(huì)輸出全部參數(shù),則第一個(gè)和第三個(gè)參數(shù)會(huì)拆開 Hello Jack Welcome to Shanghai ************ @@@@@@@@@@@@ $@ # 未加雙引號(hào),所以會(huì)輸出全部參數(shù),則第一個(gè)和第三個(gè)參數(shù)會(huì)拆開 Hello Jack Welcome to Shanghai @@@@@@@@@@@@ "*"*"*"*"*"* $* # 添加雙引號(hào)后,傳入的參數(shù)全部當(dāng)一個(gè)參數(shù)進(jìn)行輸出 Hello Jack Welcome to Shanghai "*"*"*"*"*"* "@"@"@"@"@"@ $@ # 添加雙引號(hào)后,傳入的參數(shù)全部當(dāng)獨(dú)立的參數(shù)進(jìn)行輸出 Hello Jack Welcome to Shanghai "@"@"@"@"@"@
狀態(tài)變量
- $?:獲取上一個(gè)命令或腳本的執(zhí)行狀態(tài)值(0:成功,其他:失?。?/li>
- $$:獲取當(dāng)前執(zhí)行的Shell的進(jìn)程號(hào)(PID)
- $!:獲取上一個(gè)在后臺(tái)工作的進(jìn)程的進(jìn)程號(hào)
- **$_**:獲取在些之前執(zhí)行的命令或腳本的最后一個(gè)參數(shù)
以上四個(gè)狀態(tài)變量,僅$?常用,其他三個(gè)了解即可。
在日常使場(chǎng)景中,$?主要用法如下所示:
1、判斷命令和腳本是否執(zhí)行成功
2、如腳本中調(diào)用exit 數(shù)字,則會(huì)返回該數(shù)字給$?
3、如在函數(shù)中,則可以通過return 數(shù)字將該數(shù)字返回給$?
狀態(tài)變量示例
1、$?示例:
[root@localhost Test]# ll /etc/profile -rw-r--r--. 1 root root 1819 4月 11 2018 /etc/profile [root@localhost Test]# echo $? 0 [root@localhost Test]# ll /etc/profild ls: 無法訪問/etc/profild: 沒有那個(gè)文件或目錄 [root@localhost Test]# echo $? 2
2、$$示例:
[root@localhost Test]# cat testPID.sh #!/bin/bash echo $$ > /tmp/test.pid sleep 300 [root@localhost Test]# bash testPID.sh & # 將當(dāng)前腳本調(diào)用到后臺(tái)執(zhí)行 [1] 1671 [root@localhost Test]# ps -ef | grep testPID | grep -v grep root 1671 23706 0 16:37 pts/0 00:00:00 bash testPID.sh # 查詢PID
3、!示例:!示例:!功能類似于$$,只不過是獲取上一次執(zhí)行腳本的PID
[root@localhost Test]# bash testPID.sh & [1] 24078 [root@localhost Test]# echo $! 24078 # 打印上一次在后臺(tái)執(zhí)行的進(jìn)程號(hào) [root@localhost Test]# ps -ef | grep testPID | grep -v grep root 24078 23706 0 16:42 pts/0 00:00:00 bash testPID.sh
4、$_示例:
[root@localhost Test]# bash para.sh {a..z} a b c d e f g h i j k l m n o $0 is: para.sh $1 is: a $12 is: l $# is: 26 $* is: a b c d e f g h i j k l m n o p q r s t u v w x y z "$*"is: a b c d e f g h i j k l m n o p q r s t u v w x y z $@ is: a b c d e f g h i j k l m n o p q r s t u v w x y z "$@"is: a b c d e f g h i j k l m n o p q r s t u v w x y z [root@localhost Test]# echo $_ z # 打印最后一個(gè)傳入的參數(shù)值
Bash 內(nèi)置變量
常用的內(nèi)部命令有echo、eval、exec、export、read、shift、exit。
echo
主要用于打印信息,其命令格式如下所示:
echo [options] args
常用參數(shù)如下所示:
參數(shù)選項(xiàng) | 說明 |
---|---|
-n | 不換行輸出內(nèi)容 |
-e | 解析轉(zhuǎn)義字符 |
echo常用轉(zhuǎn)義字符如下:
轉(zhuǎn)義字符 | 說明 |
---|---|
\n | 換行 |
\r | 回車 |
\t | Tab |
\b | 退格 |
\v | 縱向制表符 |
eval
當(dāng)Shell程序運(yùn)行到eval語句時(shí),將讀入?yún)?shù)args,并將它們組合成一個(gè)新的命令而后執(zhí)行。其命令格式如下所示:
eval args
exec
exec主要用于在不創(chuàng)建新的子進(jìn)程的情況下,轉(zhuǎn)而執(zhí)行指定的命令,當(dāng)指定命令執(zhí)行完后,則終止該進(jìn)程。其命令格式如下所示:
exec args
當(dāng)使用exec打開文件后,read命令每次都會(huì)將文件指針移動(dòng)到下一行進(jìn)行讀取,直至結(jié)束。因此常用來處理文件內(nèi)容。
read
從標(biāo)準(zhǔn)輸入讀取變量或字符串等信息并傳遞給其他變量,其命令格式如下所示
read args
shift
對(duì)傳入的位置參數(shù)依次向左移動(dòng)一個(gè)位置,并使用位置參數(shù)$#減1,直至0為止。其命令格式如下所示:
shift postition args
shift如果不帶參數(shù),則默認(rèn)左移1位
如傳入的參數(shù)為112 3,如執(zhí)行一次shift,則之前的3,如執(zhí)行一次shift,則之前的3變成2,2,2變成1,1,1消失。
exit
常用于退出Shell,在日常使用過程中可使用exit num來自定義返回狀態(tài)數(shù)。
Bash 內(nèi)置變量示例
1、echo
[root@localhost Test]# echo "Test";echo "Dao" Test Dao [root@localhost Test]# echo -n "Test";echo "Dao" TestDao [root@localhost Test]# echo -e "Test\tName\n Dao" Test Name Dao
2、eval
[root@localhost Test]# cat eval.sh #!/bin/bash echo "No eval" echo \$$# echo "Add eval" eval echo \$$# [root@localhost Test]# bash eval.sh a b No eval $2 # 未添加evel時(shí),$#為2,則輸出$2 Add eval b # 添加evel后,則重新對(duì)傳入的參數(shù)進(jìn)行解析,則輸出傳入的第2個(gè)參數(shù)
3、exec
[root@localhost Test]# exec ls eval.sh para.sh ping.sh testPID.sh testposition.sh [admin@localhost ~]$ # 在執(zhí)行exec后則終止當(dāng)前Shell進(jìn)程,因此從root用戶退出到普通用戶 # 與read一起讀取文件 [root@localhost ~]# seq 5 > /tmp/rand.log [root@localhost ~]# cat /tmp/rand.log 1 2 3 4 5 [root@localhost Test]# cat exec.sh #!/bin/bash exec < /tmp/rand.log while read line do echo $line done echo "Completed" [root@localhost Test]# bash exec.sh 1 2 3 4 5 Completed
4、read
可以參考公眾號(hào)中read命令一文
5、shift
[root@localhost Test]# cat shift.sh #!/bin/bash echo $1 $2 $3 $4 $5 until [ -z $1 ] do echo $@ shift 1 done [root@localhost Test]# bash shift.sh {1..5} 1 2 3 4 5 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
變量擴(kuò)展
變量擴(kuò)展說明
Shell中變量擴(kuò)展說明如下所示:
- ${var}:返回${var}的內(nèi)容
- ${#var}:返回${var}的字符長(zhǎng)度
- ${var:offset}:返回${var}從位置offset之后開始提取字符至結(jié)束
- ${var:offset:length}:返回${var}從offset之后,提取長(zhǎng)度為length的字符
- ${var#word}:返回從${var}開頭開始刪除最短匹配的word子符串
- ${var##word}:返回從${var}開頭開始刪除最長(zhǎng)匹配的word子符串
- ${var%word}:返回從${var}結(jié)尾開始刪除最短匹配的word子符串
- ${var%%word}:返回從${var}結(jié)尾開始刪除最長(zhǎng)匹配的word子符串
- ${var/oldstring/newstring}:使用newstring替換第一個(gè)匹配的字符oldstring
- ${var//oldstring/newstring}:使用newstring替換所有匹配的字符oldstring
- ${var:-word}:如果變量var的值為空或未賦值,則將word做為返回值,常用于防止變量為空或未定義而導(dǎo)致的異常
- ${var:=word}:如果變量var的值為空或未賦值,則將word賦值給var并返回其值。
- ${var:?word}:如果變量var的值為空或未賦值,則將word做為標(biāo)準(zhǔn)錯(cuò)誤輸出,否則則輸出變量的值,常用于捕捉因變量未定義而導(dǎo)致的錯(cuò)誤并退出程序
- ${var:+word}:如果變量var的值為空或未賦值,則什么都不做,否則word字符將替換變量的值
其中${var:-word}、${var:=word}、${var:?word}、${var:+word}中的冒號(hào)也可以省略,則將變量為空或未賦值修改為未賦值,去掉了為空的檢測(cè), 即運(yùn)算符僅檢測(cè)變量是否未賦值
變量擴(kuò)展示例
[root@localhost init.d]# var="This is test string" [root@localhost init.d]# echo $var This is test string [root@localhost init.d]# echo ${var} This is test string [root@localhost init.d]# echo ${#var} # 統(tǒng)計(jì)字符長(zhǎng)度 19 [root@localhost init.d]# echo ${var:5} # 從第5個(gè)位置開始截取字符 is test string [root@localhost init.d]# echo ${var:5:2} # 從第5個(gè)位置開始截取2個(gè)字符 is [root@localhost init.d]# echo ${var#This} # 從開頭刪除最短匹配的字符 is is test string [root@localhost init.d]# echo ${var##This} # 從開頭刪除最長(zhǎng)匹配的字符 is is test string [root@localhost init.d]# echo ${var%g} # 從結(jié)尾刪除最短匹配的字符 is This is test strin [root@localhost init.d]# echo ${var%%g} # 從結(jié)尾刪除最長(zhǎng)匹配的字符 is This is test strin [root@localhost init.d]# echo ${var/is/newis} # 替換第一個(gè)匹配的字符 Thnewis is test string [root@localhost init.d]# echo ${var//is/newis} # 替換所有匹配到的字符 Thnewis newis test string [root@localhost init.d]# echo $centos # 變量未定義 [root@localhost init.d]# echo ${centos:-UNDEFINE} # 變量為空,返回UNDEFINE UNDEFINE [root@localhost init.d]# centos="CentOS" [root@localhost init.d]# echo ${centos:-UNDEFINE} # 變量已經(jīng)定義,返回變量本身的值 CentOS [root@localhost init.d]# unset centos # 取消變量值 [root@localhost init.d]# echo $centos [root@localhost init.d]# result=${centos:=UNDEFINE} [root@localhost init.d]# echo $result UNDEFINE [root@localhost init.d]# echo $centos # 變量值為空,則將UNDEFINE賦值給centos UNDEFINE [root@localhost init.d]# unset centos [root@localhost init.d]# echo ${centos:?can not find variable centos} -bash: centos: can not find variable centos # 變量值為空,輸出自定義錯(cuò)誤信息 [root@localhost init.d]# centos="IS DEFINED" [root@localhost init.d]# echo ${centos:?can not find variable centos} IS DEFINED #變量值已定義,則輸出變量值 [root@localhost init.d]# unset centos [root@localhost init.d]# echo ${centos:+do nothing} # 變量值為空,什么都不操作輸出 [root@localhost init.d]# centos="do" [root@localhost init.d]# echo ${centos:+do nothing} # 變量已賦值,則輸出自定義的消息 do nothing
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
一個(gè)簡(jiǎn)潔的全自動(dòng)安裝LNMP服務(wù)器環(huán)境的Shell腳本分享
這篇文章主要介紹了一個(gè)簡(jiǎn)潔的全自動(dòng)安裝LNMP服務(wù)器環(huán)境的Shell腳本分享,本文腳本在生產(chǎn)環(huán)境上使用了一年多,腳本代碼簡(jiǎn)單唯美,需要的朋友可以參考下2014-12-12Shell中的函數(shù)、函數(shù)定義、作用域問題介紹
這篇文章主要介紹了Shell中的函數(shù)、函數(shù)定義、作用域問題介紹,本文講解了Shell中函數(shù)的定義、自定義函數(shù)的例子、作用域問題等內(nèi)容,需要的朋友可以參考下2014-11-11linux定時(shí)任務(wù)基礎(chǔ)命令介紹(14)
這篇文章主要為大家詳細(xì)介紹了linux定時(shí)任務(wù)基礎(chǔ)命令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12shell字符串截取報(bào)錯(cuò):Bad substitution的解決
這篇文章主要介紹了shell字符串截取報(bào)錯(cuò):Bad substitution的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Linux命令學(xué)習(xí)之原來最簡(jiǎn)單的ls命令這么復(fù)雜
ls命令應(yīng)該是我們最常用的命令之一了,但是我們可能容易忽略那些看起來最簡(jiǎn)單的東西。本文就來和大家詳細(xì)聊聊ls命令的使用,需要的可以了解一下2022-10-10利用Linux中的crontab實(shí)現(xiàn)分布式項(xiàng)目定時(shí)任務(wù)功能
crond是Linux用來定期執(zhí)行程序的命令.這篇文章主要介紹了利用Linux中的crontab實(shí)現(xiàn)分布式項(xiàng)目定時(shí)任務(wù),需要的朋友可以參考下2018-01-01Linux中實(shí)現(xiàn)非登錄系統(tǒng)用戶執(zhí)行命令的方法
Linux系統(tǒng)中,管理員經(jīng)常需要通過一個(gè)無法登錄shell的系統(tǒng)用戶來執(zhí)行特定的命令,這種需求在管理多用戶系統(tǒng)或自動(dòng)化任務(wù)時(shí)尤為常見,下面,我們將詳細(xì)講解如何實(shí)現(xiàn)這一需求,并深入分析其背后的原理,需要的朋友可以參考下2024-01-01