(轉)Shell全局變量、局部變量與特殊變量筆記總結


Shell全局變量、局部變量與特殊變量筆記總結

原文:http://blog.csdn.net/apollon_krj/article/details/70148022

變量類型:全局變量(環境變量)和局部變量(本地變量) 
環境變量可以在定義它們的shell及其派生出來的任意子進程的shell中使用。局部變量只能在定義它們的函數/腳本中使用。還有一些變量是用戶創建的,其他的則是專用的shell變量。

1、全局變量(環境變量):

環境變量可用於定義shell的運行環境,環境變量可以在配置文件中定義與修改,也可以在命令行中設置,但是命令行中的修改操作在終端重啟時就會丟失,因此最好在配置文件中修改(用戶家目錄的“.bash_profile“文件或者全局配置“/etc/profile”、“/etc/bashrc”文件或者“/etc/profile.d”文件中定義。)將環境變量放在profile文件中,每次用戶登錄時這些變量值將被初始化。比如HOME、USER、SHELL、UID等再用戶登錄之前就已經被/bin/login程序設置好了。

常見系統環境變量:

TMOUT:設置自動退出的誤操作等待時間 
HOSTTYPE:系統文件系統類型 
HISTSIZE:歷史命令記錄條數 
HOME:用戶登錄時進入的目錄,家目錄 
UID:當前用戶的id 
SHELL:當前shell解釋器 
PWD:當前所在路徑(每改變一次目錄,該值就會改變) 
PATH:可執行文件默認路徑 
等等。

可以用echo來顯示查看全局變量(eg:echo $HOME)。env(或printenv)、set也可以用來查看系統的環境變量,但不是單獨查看。而用unset臨時取消環境變量(eg:unset USER),要永久生效還是要寫到配置文件中

自定義環境變量(采用export): 
①export 變量名=value 
②變量名=value;export 變量名 
③declare -x 變量名=value 
這里依舊是臨時生效,在shell終端關閉后就消失了,寫到配置文件中則永久生效(注意:寫到配置文件中后需要運行一遍配置文件的腳本才可生效,否則等重啟時生效)

命令行的三種方式測試如下: 
這里寫圖片描述

關於環境變量PATH與export的更詳細的內容,可參考: Linux環境變量與系統編程學習筆記

2、局部變量(本地變量):

本地變量在用戶當前的shell生存期的腳本中使用。在一個函數中將某個變量聲明為local,則該變量就是一個局部變量,只在本函數中有效。 
定義:

變量名=value 
變量名=’value’ 
變量名=”value” 
shell中變量名的要求:一般遵循字母、數字、下滑線組成,不能以數字開頭

eg:以下腳本執行后(交互式非交互式都可以測試)輸出什么(c{c}等同)?

a=192.168.1.1 b='192.168.1.2' c="192.168.1.3" echo "A=$a" echo "B=$b" echo "C=${c}" a=192.168.1.1-$b b='192.168.1.2-$b' c="192.168.1.3-$b" echo "A=$a" echo "B=$b" echo "C=${c}"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

輸出結果如下:

A=192.168.1.1 B=192.168.1.2 C=192.168.1.3 A=192.168.1.1-192.168.1.2 B=192.168.1.2-$b C=192.168.1.3-192.168.1.2-$b
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

總結分析: 
單引號與雙引號的區別在於:單引號內若存在變量,存在的變量當做字符串不會被解析,原樣輸出;而雙引號中若存在變量,該變量會被解析出其具體的值再加入到字符串中。①不加引號可以直接定義內容包含數字、字符串、路徑名等,適合定義數字②單引號適合於純定義字符串,③而雙引號適合於字符串的內容中包含有變量的內容的定義。(習慣:數字以及不帶空格的簡單字符串不加引號,其它長的特別是有空格的字符串加雙引號;遇到“$變量名”,但不想解析的加單引號,但一般出現$都是為了解析變量,所以單引號較少使用)

注意:單引號與雙引號的特點不具有普遍性,如下: 
在普通shell中:

ETT=123 echo '$ETT' //打印$ETT(單引號不解析) echo "$ETT" //打印123(雙引號解析)
  • 1
  • 2
  • 3

而在awk中調用shell變量:

awk 'BEGIN {print '$ETT'}'//打印123(單引號解析) awk 'BEGIN {print "$ETT"}'//打印$ETT(雙引號不解析)
  • 1
  • 2

雖然在awk中不具有普遍性,但是在普通Shell中還是具有普遍性的。

3、關於局部變量的其它一些問題

①用反引號將命令的結果作為變量名是常用的方法,eg:cmd=`date +%F` ②用$符號將命令的結果作為變量名也比較常用,eg:cmd=$(date +%F) ③變量在大括號上的使用:在以時間、主機名等為包名一部分來打包的時候常用
  • 1
  • 2
  • 3

eg1:用時間作為文件名的一部分打包

cmd=$(date +%F) //由於`date +%F`的反引號不容易辨認,就不太使用`date +%F` tar -zcf code_$(date+ %F)_kang.tar.gz /etc //沒有問題 tar -zcf code_`date +%F`_kang.tar.gz /etc //沒有問題 tar -zcf code_kang_$cmd.tar.gz /etc //沒有問題 tar -zcf code_$cmd_kang.tar.gz /etc //會有歧義,因為系統會不清楚是應該解析$cmd還是cmd_kang tar -zcf code_${cmd}_kang.tar.gz /etc //不會有歧義
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

對后兩種測試結果如下(不加{}的與理想結果是不符的): 
這里寫圖片描述 
eg2:用主機名與時間打包

cmd=$(date +%F) host=$(hostname) tar -zcf code_${cmd}_${host}.tar.gz /etc 
  • 1
  • 2
  • 3

測試: 
這里寫圖片描述 
養成將字符串括起來使用的習慣防止不易發現的錯誤。

4、Shell的特殊變量:

$0:獲取當前執行的shell腳本的文件名(執行時給定的是完整路徑則獲取到的也是完整路徑)
  • 1

兩個命令與$0的組合測試:獲取一個帶路徑的文件的路徑名與文件名兩部分

dirname(獲取目錄名部分) basename(獲取文件名部分)
  • 1
  • 2

測試: 
這里寫圖片描述

$n:獲取當前執行的shell腳本的第n個參數,如果n=0則獲取的是腳本的文件名。如果n>9則需要用大括號括起來,eg:${21}
  • 1

測試$n:

這里寫圖片描述

$*:獲取當前執行的shell的所有參數,將所有的命令行參數視為單個字符串
$#:獲取當前shell命令行中參數的總個數 $@:這個程序的所有參數"$1" "$2" "$3" "...",這是將參數傳遞給其它程序的最佳方式,因為它會保留所有內嵌在每個參數里的任何空白 $*與$@的區別: $*將命令行的所有參數視為一個字符串:"$1$2$3..." $@將命令行的每個參數視為單個的字符串:"$1" "$2" "$3" ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

基本測試如下: 
這里寫圖片描述

獲取狀態變量:
$$:獲取當前的shell進程號 $?:獲取執行上一個指令的返回值(0為成功,非零為失敗),可以對上一個命令執行是否成功進行判斷。 $_:在此之前執行的命令或腳本的最后一個參數
  • 1
  • 2
  • 3
  • 4

$?變量其實獲取的是上一個程序返回給父進程shell的返回值(該值在0-255之間:0表示運行成功,2表示權限拒絕,1~125為運行失敗原因是腳本命令、系統命令錯誤或參數傳遞錯誤,126為找到該命令但是無法執行,127為無該命令/程序,>128表示命令被系統強制結束)

$?的不同返回值測試: 
這里寫圖片描述 
$?的值范圍測試如下:

這里寫圖片描述

$?在腳本中的應用: 
常用來判斷上一步是否成功(壓縮失敗打印ERROR壓縮成功打印OK): 
這里寫圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM