bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.htmlphp
變量存在於內存中。假設變量str,設置或修改變量屬性時,不帶$號,只有引用變量的值時才使用$號。也就是說在內存中,標記變量的變量名稱是str,而不是$str。html
環境變量就是運行在"環境"上下文的,在這個上下文均可以引用。例如,常見的cd、ls等命令嚴格來講應該使用絕對路徑如/bin/ls來執行,因爲/bin目錄加入到了PATH環境變量中,系統本身會去尋找PATH下的路徑是否有該命令。mysql
環境變量經常使用大寫字母表示。常見的環境變量有HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。分別表示當前主機名、SHELL的路徑即bash的類型、history保存多少記錄、當前用戶名、自動搜索路徑、當前目錄、使用的語系(臨時修改語系時就改這個變量)、當前用戶的家目錄、當前登陸的用戶。linux
使用env或者export能夠查看當前用戶的環境變量。web
[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能夠輸出變量的值。sql
[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。shell
[root@xuexi tmp]# PATH=/usr/local/mysql/bin:$PATH
這裏也能看到兩個PATH第一個沒使用$,第二個使用了。當對變量自己進行操做,則不使用$,當對變量值進行操做,則使用$。apache
腳本語言是弱類型的語言,變量一般不須要特意聲明甚至不須要初始化,在腳本運行時由解釋器進行解釋運算,解釋器知道變量在何時是什麼類型,因此直接賦值使用便可。bash中,變量默認都是字符串類型,不管是否使用引號賦值,都以字符串方式存儲。vim
1.變量賦值方式: str=value 。注意等號左右沒有空格。若是有空格就是進行比較運算符的比較運算了。bash
2.變量引用方式:$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!
3.釋放變量: unset str ,注意變量名前不加前綴$。
[root@xuexi ~]# unset str
4.查看全部的變量:不接任何參數的set或者declare命令,輸出結果中包含了普通變量和環境變量。
5.定義只讀變量: readonly str 。這時將沒法修改變量值也沒法unset變量,只有從新登陸shell才能繼續使用只讀變量。
6.臨時將普通變量升級爲環境變量: 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!
普通的變量在腳本結束或退出登陸後就失效,而且只對當前shell有效,其餘用戶和當前用戶的子shell都沒法使用。
使用export能夠升級爲臨時局部的環境變量,只對當前用戶的當前shell和子shell有效,退出腳本和退出登陸後也失效。
若是想要設置永久的且全局的變量,一種方法是將變量的設置語句放入到/etc/profile文件中,由於每一個用戶登陸時,都會調用該文件並執行其中的語句。若是想當即加載此文件中的配置使得臨時添加的設置當即生效,只需source該文件便可。
[root@xuexi ~]# source /etc/profile
/etc/profile文件是bash的全局配置文件,還有每一個用戶的配置文件~/.bash_profile,此文件中的變量將只對對應的用戶生效。
此外,還有幾個配置bash環境配置文件,具體的見bash環境配置流程。
在使用"${}"方式引用變量時,變量名前加上#就能夠查看該變量的字符長度。空格也算入長度。例如:
[root@xuexi ~]# echo ${#str} 12 [root@xuexi ~]# echo ${#PATH} 92
declare [+/-][選項] 變量名
選項說明:
-/+:給變量設定類型屬性,取消給變量設定的類型屬性
-i:聲明爲整型
-x:聲明爲環境變量
-p:顯示變量名和值
例如,聲明一個環境變量 declare -x str ,取消該變量 declare +x str 。
$?:上一條代碼執行的回傳指令,回傳0表示標準輸出,即正確執行,不然爲標準錯誤輸出。
$$:當前shell的PID。除了執行bash命令和shell腳本時,$$不會繼承父shell的值,其餘類型的子shell都繼承。
$BASHPID:當前shell的PID,這和"$$"是不一樣的,由於每一個shell的$BASHPID是獨立的。而"$$"有時候會繼承父shell的值。
$!:最近一次執行的後臺進程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
使用 shift [N] 能夠指定參數輪替,每執行一次 shift N 就踢掉N個參數,默認N爲1。
例如在腳本中:
echo $1 # # 輸出第一個參數值 shift 2 # # 踢掉前兩個參數,第三個參數變成$1 echo $1 # # 此時$1的值爲第三個參數的值 shift # # 又踢掉一個參數,第四個參數變成$1 echo $1 # # 輸出第四個參數
一、變量中字符的長度: ${#VARNAME}
二、變量賦值等:
${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=word}:在man bash裏沒有該定義,可是經測試,等價於${para:=word}。
${parameter:offset}:取子串,從offset處的後一個字符開始取到最後一個字符;
${parameter:offset:length}:取子串,從offset處的後一個字符開始,取lenth長的子串;
其中 ${parameter:-word} 最經常使用,最後兩個是截取字符串的,偶爾也會用到。
三、腳本配置文件
配置文件中的變量值能夠在腳本中被使用
要在腳本中調用配置文件,直接使用 source config_file 或 . config_file
服務啓動腳本支持配置文件:/etc/sysconfig/服務腳本同名的配置文件
四、局部變量,在函數中定義局部變量使其不影響函數外的同名變量
local VAR_NAME=
五、命令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
實際上是對變量實現的功能,只是使用文件名的說法比較典型,且容易理解它的用途。
例如,將文件名"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個字節,即第七、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