SHELL腳本--變量(基礎)

bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.htmlphp


變量存在於內存中。假設變量str,設置或修改變量屬性時,不帶$號,只有引用變量的值時才使用$號。也就是說在內存中,標記變量的變量名稱是str,而不是$strhtml

1.4.1 環境變量

環境變量就是運行在"環境"上下文的,在這個上下文均可以引用。例如,常見的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

1.4.2 普通變量

腳本語言是弱類型的語言,變量一般不須要特意聲明甚至不須要初始化,在腳本運行時由解釋器進行解釋運算,解釋器知道變量在何時是什麼類型,因此直接賦值使用便可。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!

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。除了執行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

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其餘基礎

一、變量中字符的長度: ${#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

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個字節,即第七、89、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
相關文章
相關標籤/搜索