shell 腳本中常用的內置變量(Bash 內置變量)
$FUNCNAME、$LINENO、$PWD
FUNCNAME
和LINENO
變量經常用於腳本的調試
FUNCNAME
表示當前函數的名字,作用范圍僅限函數中使用,在函數外無值
LINENO
表示當前所在腳本中變量出現在的行號
PWD
表示當前目錄, 對應於 pwd
命令
現有個腳本 a.sh
內容如下
#!/bin/bash testa() { echo 'func='$FUNCNAME,$LINENO } testa echo 'lineno:'$LINENO echo 'xx:'$FUNCNAME echo 'curpath:'$PWD
執行 ./a.sh
命令, 輸出如下
[tt@ecs-centos-7 ~]$ ./a.sh
func=testa,6
lineno:12
xx:
curpath:/home/tt
在 testa
函數中 FUNCNAME
變量值是 testa
,也即函數名字,在函數外部無值
LINENO
變量無論是在函數中還是函數外,都表示當前所在的行號
$$、$PPID
這兩個變量依次表示當前進程ID和父進程ID
現有 a.sh
腳本,內容如下
sleep 20
睡眠語句是為瞭讓執行腳本進程暫緩退出,在另一個終端中驗證輸出的結果
#!/bin/bash #set -u echo 'cur pid:'$$ echo 'parent pid:'$PPID sleep 20
在當前終端執行 ./a.sh
,結果如下
[tt@ecs-centos-7 ~]$ ./a.sh cur pid:13095 parent pid:12982
在執行a.sh
的腳本進程退出之前,打開另一個終端,執行 ps -o pid,ppid,time,cmd -p 12982,13095
命令,結果如下
[tt@ecs-centos-7 ~]$ ps -o pid,ppid,time,cmd -p 12982,13095 PID PPID TIME CMD 12982 12981 00:00:00 -bash 13095 12982 00:00:00 /bin/bash ./a.sh
從上面的結果可以看出, 執行 ./a.sh
命令之後,$$ 變量表示的是 執行a.sh
腳本的進程ID 13095 ,而 12982 是它的父進程ID,也即是 PPID
變量的值,它是當前bash的實例
$0,$1,$2…$n、$#
$#
表示從命令行傳入腳本的參數數量
$0,$1,$2...$n
是從命令行傳遞到腳本的參數 $0
是腳本本身的名字
$1
是第一個參數
$2
是第二個參數,依此類推
$n
是第n個參數
第十個參數及以後的參數必須要用大括號括起來,例如: ${10}、${11}、${12} 依次表示第十個變量、第十一個變量、第十二個變量
$*、$@
都表示位置參數,不過它們之間也有些不同點
使用 $*
時,如果加上雙引號,即 $* 的形式,那所有位置的參數會被當作一個單詞來處理,如果不包含雙引號,即 $* 的形式,則每個位置的參數都被當作一個獨立的單詞來處理
而對於 $@
,無論是否加上雙引號,每個位置的參數都被當作一個獨立的單詞來處理
現有c.sh
, 內容如下
#!/bin/bash cnt=1 echo 'test 1111' for var in "$*" do echo "arg$cnt="$var let "cnt+=1" done echo cnt=1 echo 'test 2222' for var in $* do echo "arg$cnt="$var let "cnt+=1" done echo cnt=1 echo 'test 3333' for var in "$@" do echo "arg$cnt="$var let "cnt+=1" done echo cnt=1 echo "test 4444" for var in $@ do echo "arg$cnt="$var let "cnt+=1" done
執行 ./c.sh 1 2 3
,結果如下
[root@ecs-centos-7 ~]# ./c.sh 1 2 3
test 1111
arg1=1 2 3test 2222
arg1=1
arg2=2
arg3=3test 3333
arg1=1
arg2=2
arg3=3test 4444
arg1=1
arg2=2
arg3=3
從上面的結果可以看出,對於 $* 來說,加瞭雙引號之後所有位置參數就會被視為一個單詞
對於 $@ 來說,是否加雙引號,結果都是一樣的
所以,僅在使用雙引號時,$* 和 $@ 才會有差異
$?
命令、函數或者腳本的退出狀態,在判斷命令的執行結果或者函數的調用結果時很有用處
現有 e.sh
和 f.sh
測試腳本
e.sh 腳本
#!/bin/bash test_func() { if [[ $1 -eq 10 ]]; then return 5 fi return 6 } if [ $# -ge 1 ]; then name="$1" shift 1 $name "$@" fi
f.sh 腳本
#!/bin/bash sh e.sh test_func 3 echo 'exit code1:'$? sh e.sh test_func 10 echo 'exit code2:'$? test -f $PWD/xx.txt echo 'exit code3:'$? test -f $PWD/e.sh echo 'exit code4:'$?
執行 ./f.sh
命令,結果如下
[root@ecs-centos-7 ~]# ./f.sh
exit code1:6
exit code2:5
exit code3:1
exit code4:0
腳本 e.sh
中 test_func
函數功能是:當參數等於10時,退出狀態為 5,否則為 6
sh e.sh test_func 3
命令會調用 e.sh
腳本中的 test_func
函數,傳入參數是 3,所以退出狀態為 6,同理可知, sh e.sh test_func 10
命令的退出狀態是 5
在Linux中,命令執行成功,退出狀態為 0 ,失敗則為非 0
test -f $PWD/xx.txt
命令是檢查當前目錄是否存在 xx.txt
文件,因當前目錄並不存在 xx.txt
,所以命令執行失敗,退出狀態為非 0
由於e.sh
存在於當前目錄下,所以 test -f $PWD/e.sh
命令執行成功,退出狀態為 0
$IFS
此變量用於 Bash 識別字符串或單詞邊界,默認值是空格,腳本中根據需要可以修改此變量的值
現有 b.sh
腳本,內容如下
#!/bin/bash va="a:b:c" vb="x-y-z" vc="e,f,g" IFS=":" echo 'va:'$va echo 'vb:'$vb echo 'vc:'$vc echo IFS="-" echo 'va:'$va echo 'vb:'$vb echo 'vc:'$vc echo IFS="," echo 'va:'$va echo 'vb:'$vb echo 'vc:'$vc
執行 ./b.sh
結果如下
[tt@ecs-centos-7 ~]$ ./b.sh
va:a b c
vb:x-y-z
vc:e,f,gva:a:b:c
vb:x y z
vc:e,f,gva:a:b:c
vb:x-y-z
vc:e f g
從結果可以看出,當 $IFS
為 :
時,字符串 "a:b:c"
被解析成 a b c
當 $IFS
為 -
時,字符串 "x-y-z"
被解析成 x y z
當 $IFS
為 ,
時,字符串 "e,f,g"
被解析成 e f g
$HOME、$USER、$UID、$GROUPS
HOME: 用戶home目錄 USER: 當前用戶名 UID: 當前用戶ID GROUPS: 當前用戶組ID
[tt@ecs-centos-7 ~]$ echo $HOME /home/tt [tt@ecs-centos-7 ~]$ echo $USER tt [tt@ecs-centos-7 ~]$ echo $UID 1003 [tt@ecs-centos-7 ~]$ echo $GROUPS 1003
$HOSTTYPE、$MACTYPE、$OSTYPE
這些變量都表示系統硬件
[tt@ecs-centos-7 ~]$ echo $HOSTTYPE x86_64 [tt@ecs-centos-7 ~]$ echo $MACHTYPE x86_64-redhat-linux-gnu [tt@ecs-centos-7 ~]$ echo $OSTYPE linux-gnu
小結
本文介紹瞭一些常用的 Bash 內置變量,對於一些生僻或者平常很少用到的變量可以自行查閱相關資料
以上就是shell 腳本中常用的內置變量(Bash 內置變量)的詳細內容,更多關於shell內置變量的資料請關註WalkonNet其它相關文章!