本文目錄: 1.4.1 環境變數 1.4.2 普通變數 1.4.3 修改變數的生命周期和作用域 1.4.4 獲取變數的長度 1.4.5 declare聲明變數 1.4.6 位置變數和特殊變數 1.4.7 shift輪替變數 1.4.8 shell其它基礎 1.4.9 變數的切分、提取和替換 變數存在 ...
本文目錄:
變數存在於記憶體中。假設變數str,設置或修改變數屬性時,不帶$號,只有引用變數的值時才使用$號。也就是說在記憶體中,標記變數的變數名稱是str,而不是$str。
1.4.1 環境變數
環境變數就是運行在"環境"上下文的,在這個上下文都可以引用。例如,常見的cd、ls等命令嚴格來說應該使用絕對路徑如/bin/ls來執行,由於/bin目錄加入到了PATH環境變數中,系統自己會去尋找PATH下的路徑是否有該命令。
環境變數常用大寫字母表示。常見的環境變數有HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。分別表示當前主機名、SHELL的路徑即bash的類型、history保存多少記錄、當前用戶名、自動搜索路徑、當前目錄、使用的語系(臨時修改語系時就改這個變數)、當前用戶的家目錄、當前登錄的用戶。
使用env或者export可以查看當前用戶的環境變數。
[root@xuexi ~]# env XDG_SESSION_ID=411 HOSTNAME=xuexi.longshuai.com TERM=linux SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=172.16.10.1 10171 22 QTDIR=/usr/lib64/qt-3.3 QTINC=/usr/lib64/qt-3.3/include SSH_TTY=/dev/pts/0 QT_GRAPHICSSYSTEM_CHECKED=1 USER=root LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: MAIL=/var/spool/mail/root PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/sersync:/root/bin PWD=/root LANG=en_US.UTF-8 HISTCONTROL=ignoredups SHLVL=1 HOME=/root LOGNAME=root QTLIB=/usr/lib64/qt-3.3/lib SSH_CONNECTION=172.16.10.1 10171 172.16.10.3 22 LESSOPEN=||/usr/bin/lesspipe.sh %s XDG_RUNTIME_DIR=/run/user/0 _=/usr/bin/env
使用echo可以輸出變數的值。
[root@xuexi ~]# echo $PATH /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
例如,在PATH環境變數中新加入一個目錄/usr/local/mysql/bin。
[root@xuexi tmp]# PATH=/usr/local/mysql/bin:$PATH
這裡也能看到兩個PATH第一個沒使用$,第二個使用了。當對變數本身進行操作,則不使用$,當對變數值進行操作,則使用$。
1.4.2 普通變數
腳本語言是弱類型的語言,變數通常不需要特地聲明甚至不需要初始化,在腳本運行時由解釋器進行解釋運算,解釋器知道變數在什麼時候是什麼類型,所以直接賦值使用即可。bash中,變數預設都是字元串類型,不論是否使用引號賦值,都以字元串方式存儲。
變數賦值方式:str=value,其實是set str=value,省略了set關鍵字。註意等號左右沒有空格。如果有空格就是進行比較運算符的比較運算了。
變數引用方式:$str或者${str},例如echo "the var is ${str}"。
[root@xuexi tmp]# str='Hello World!' [root@xuexi tmp]# echo "We will say ${str}" We will say Hello World!
釋放變數:unset str,註意變數名前不加首碼$。
[root@xuexi ~]# unset str
查看所有的變數:不接任何參數的set或者declare命令,輸出結果中包含了普通變數和環境變數。
定義只讀變數:readonly str。這時將無法修改變數值也無法unset變數,只有重新登錄shell才能繼續使用只讀變數。
臨時將普通變數升級為環境變數:export str或者賦值時export str="value",這樣$str就可以在當前shell和子shell中使用,但是退出腳本或者重新登錄shell都會取消export效果。
[root@xuexi ~]# str='Hello World!';echo $str Hello World! [root@xuexi ~]# bash # 開啟子shell [root@xuexi ~]# echo ${str} # 子shell中查看變數結果發現沒有該變數。
在子shell中查看變數,結果竟然發現沒有該變數。這是因為$str的作用域只在當前shell,要想在子shell中也能引用普通變數,則需要使用export升級為環境變數。
[root@xuexi ~]# exit # 退出子shell [root@xuexi ~]# export str # 回到父shell升級該變數 [root@xuexi ~]# bash [root@xuexi ~]# echo $str Hello World!
1.4.3 修改變數的生命周期和作用域
普通的變數在腳本結束或退出登錄後就失效,並且只對當前shell有效,其他用戶和當前用戶的子shell都無法使用。
使用export可以升級為臨時局部的環境變數,只對當前用戶的當前shell和子shell有效,退出腳本和退出登錄後也失效。
如果想要設置永久的且全局的變數,一種方法是將變數的設置語句放入到/etc/profile文件中,因為每個用戶登錄時,都會調用該文件並執行其中的語句。如果想立即載入此文件中的配置使得臨時添加的設置立即生效,只需source該文件即可。
[root@xuexi ~]# source /etc/profile
/etc/profile文件是bash的全局配置文件,還有每個用戶的配置文件~/.bash_profile,此文件中的變數將只對對應的用戶生效。
此外,還有幾個配置bash環境配置文件,具體的見bash環境配置流程。
1.4.4 獲取變數的長度
在使用${}方式引用變數時,變數名前加上#就可以查看該變數的字元長度。空格也算入長度。例如:
[root@xuexi ~]# echo ${#str} 12 [root@xuexi ~]# echo ${#PATH} 92
1.4.5 declare聲明變數
declare [+/-][選項] 變數名
選項說明:
-/+:給變數設定類型屬性,取消給變數設定的類型屬性
-i:聲明為整型
-x:聲明為環境變數
-p:顯式指定變數被聲明的類型
例如,聲明一個環境變數declare -x str,取消該變數declare +x str。
1.4.6 位置變數和特殊變數
$?:上一條代碼執行的回傳指令,回傳0表示標準輸出,即正確執行,否則為標準錯誤輸出。
$$:表示當前登錄的shell的PID。
$!:後臺運行的最後一個進程PID。
$#:統計參數的個數。
$@:所有單個參數,如"a""b""c""d"。
$*:所有參數的整體,如“abcd”。
$0:腳本名。
$1……$n:參數位置。
使用下麵的腳本來驗證位置變數和特殊變數。
root@xuexi tmp]# vim var.sh #!/bin/bash # 測試各種變數的作用,包括預定義和自定義變數 echo '$?:'$? echo '$$:'$$ echo '$!:'$! echo '$#:'$# echo '$@:'$@ echo '$*:'$* echo '$0:'$0 echo '$1:'$1 echo '$2:'$2 echo '$3:'$3 echo '$4:'$4
使用5個參數來運行該腳本。
[root@xuexi tmp]# sh ./var.sh a b c d e $?:0 $$:6089 $!: $#:5 $@:a b c d e $*:a b c d e $0:./var.sh $1:a $2:b $3:c $4:d
1.4.7 shift輪替變數
使用shift [N]可以指定參數輪替,每執行一次shift N就踢掉N個參數,預設N為1。
例如在腳本中:
echo $1 # # 輸出第一個參數值 shift 2 # # 踢掉前兩個參數,第三個參數變成$1 echo $1 # # 此時$1的值為第三個參數的值 shift # # 又踢掉一個參數,第四個參數變成$1 echo $1 # # 輸出第四個參數
1.4.8 shell其他基礎
1、變數中字元的長度:${#VARNAME}
2、變數賦值等:
${parameter:-word}:如果parameter為空或未定義,則變數展開為“word”;否則展開為parameter的值;
${parameter-word}:和${parameter:-word}幾乎等價,除了parameter設置了但為空時,變數的結果將是null,而非word。在/etc/init.d/httpd中有此用法。
${parameter:+word}:如果parameter為空或未定義,不做任何操作,即仍然為空;否則展開為“word”值;
${parameter:=word}:如果parameter為空或未定義,則變數展開為“word”,否則為parameter自身;
${parameter:offset}:取子串,從offset處的後一個字元開始取到最後一個字元;
${parameter:offset:length}:取子串,從offset處的後一個字元開始,取lenth長的子串;
其中${parameter:-word}最常用,最後兩個是截取字元串的,偶爾也會用到。
3、腳本配置文件
配置文件中的變數值可以在腳本中被使用
要在腳本中調用配置文件,直接使用source config_file或“. config_file”
服務啟動腳本支持配置文件:/etc/sysconfig/服務腳本同名的配置文件
4、局部變數,在函數中定義局部變數使其不影響函數外的同名變數
local VAR_NAME=
5、命令mktemp創建臨時文件或目錄
mktemp [-d] /tmp/file.XX # X指定越多,隨機生成的尾碼就越長,其中-d表示創建臨時目錄。
例如:
[root@xuexi ~]# mktemp haha.XXX haha.oOe [root@xuexi ~]# mktemp -d haha.XXX haha.npz [root@xuexi ~]# touch haha.npz/A.txt
1.4.9 變數的切分、提取和替換
其實是對變數實現的功能,只是使用文件名的說法比較典型,且容易理解它的用途。
例如,將文件名“Linux.docx.jpg”存放到變數file_name中,然後執行從左向右或從右向左的刪除或貪婪刪除。
[root@xuexi tmp]# file_name="Linux.docx.jpg" [root@xuexi tmp]# file_name_greedy=${file_name%%.*} [root@xuexi tmp]# file_name_nongreedy=${file_name%.*} [root@xuexi tmp]# extention_name_greedy=${file_name##*.} [root@xuexi tmp]# extention_name_nongreedy=${file_name#*.} [root@xuexi tmp]# echo -e "${file_name_greedy}\n${file_name_nongreedy}\n${extention_name_greedy}\n${extention_name_nongreedy}" Linux Linux.docx jpg docx.jpg
${var%%.*}和${var%.*}中的“%%.*”表示從右向左匹配“.*”並刪除,由於Linux.docx.jpg有兩種符合條件的匹配:“.jpg”和“.docx.jpg”,所以使用兩個%%表示貪婪刪除,即刪除最長匹配“.docx.jpg”。可以使用一個%表示非貪婪刪除,表示刪除最短的匹配即“.jpg”。
${var##*.}和${var#*.}中的“##*.”表示從左向右匹配“*.”並執行貪婪刪除,即刪除“Linux.docx.”,同理“#*.”表示非貪婪刪除,即刪除“Linux.”。
除了刪除,還可以實現提取和替換的功能。
[root@xuexi tmp]# echo "${file_name:0:5}" # 提取第0個位元組後的5個位元組,即1-5位元組 Linux [root@xuexi tmp]# echo "${file_name:6:4}" # 提取第6個位元組後的4個位元組,即第7、8、9、10位元組 docx [root@xuexi tmp]# echo "${file_name/jpg/pdf}" # 非貪婪替換jpg為pdf,即只替換從左向右的第一個 Linux.docx.pdf [root@xuexi tmp]# echo "${file_name//jpg/pdf}" # 貪婪替換jpg為pdf,即所有的jpg都替換為pdf Linux.docx.pdf
不錯的功能是替換。有時候想要刪除PATH環境變數中的某個路徑,可以使用變數替換的功能,似乎沒法使用變數切分來實現。例如:
[root@toystory php]# echo $A /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/apache/bin:/usr/local/mysql:/usr/local/apache/bin
註意,由於可能多次讀取了配置文件,導致PATH中出現了重覆的路徑。現在想刪除其中一個路徑。使用下麵的命令就可以實現路徑刪除,註意其中使用了轉義符號,並且變數替換的替換值留空了表示刪除前面匹配的部分。
[root@toystory php]# B=${A/:\/usr\/local\/apache\/bin/} [root@toystory php]# echo $B /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql:/usr/local/apache/bin
回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html