第一部分:Bash變量概述
Shell和其他語言的對比:
1.PHP和Java主要實現功能
2.所見即所得,Shell用於簡化管理操作
一、什麼是變量與變量分類
1.什麼是變量:
變量是計算機內存的單元,其中存放的值可以改變
變量讓你能夠把程序中準備使用的每一段數據都賦給一個簡短易於記憶的名字
2.變量命名規則:
變量名必須以字母或下劃線打頭,名字中間只能由字母、數字和下劃線組成;
變量名的長度不可以超過255個字符;
變量名在有效範圍內必須是唯一的;
在Bash中,變量的默認類型都是字符型;
在任何系統中,目錄名,文件名,變量名都要有含義;
3.變量按照存儲數據分類
字符串型
[root@localhost ~]# a123 = “hello,shell”
整型
浮點型
日期型
4.變量的分類
用戶自定義變量:變量自定義的,內容名稱作用都可以自定義;
環境變量:這種變量中主要保存的是和紫銅操作環境相關的數據。變量可以自定義的,但是對系統生效的環境變量名和變量作用是固定的,一部分可以自定義;
位置參數變量:這種變量主要是用來向腳本當中傳遞參數或數據的,變量名不能自定義,變量作用也是固定的,預定義變量的一種,作用單一,數量多;
預定義變量:是Bash中已經定義好的變量,變量名不能自定義,變量作用也是固定的,不可以自己增加,完全系統定義的,只能人爲的修改其中的值;
二、用戶自定義變量
1.定義變量
變量名=變量值
例如:
x=5
name=”shell”
注:“=”左右不能有空格,加了之後系統覺得你輸入的是命令,命令需要用空格隔開;變量名開頭必須是下劃線或者字母
[root@localhost ~]# x=5 [root@localhost ~]# name=”shell” [root@localhost ~]# 5x=6 -bash: 5x=6: command not found [root@localhost ~]# name = “shell” -bash: name: command not found
單引號與雙引號區別:
' ' :單引號,在單引號中所有的特殊符號,如“$”和“`”和“\”都沒有特殊含義
" " :雙引號。在雙引號中特殊符號都沒有特殊含義,但是“$”和“`”和“\”例外擁有
“調用變量的值”,“引用命令”和“轉義符”的特殊含義
2.變量的調用
$:用於選取變量所對應得值,如需要調用變量name的值,使用$name的方式就能得到變量的值
echo $變量名#echo適用於輸出的命令
例如:
echo $x echo $name
注:Shell和PHP在定義變量上就不一樣的:PHP是 $x=5,Shell是x=5;調用時都需要加$x
[root@localhost ~]# echo $x
5#默認定義的是字符型,也就是說這個”5“是字符,而不是數字
[root@localhost ~]# echo $name shell [root@localhost ~]# y=6 [root@localhost ~]# z=$x+$y [root@localhost ~]# echo $z 5+6
3.變量疊加
例如:
x=123 x=”$x”456 x=${x}789
如果只是再次賦值,那麼不會出現疊加,而是覆蓋:
[root@localhost ~]# x=123 [root@localhost ~]# echo $x 123#這裏將不是上面出現的5,也不是5123 [root@localhost ~]# x=”$x”456 [root@localhost ~]# echo $x 123456#疊加,可以使變量做部分修改,特別是變化出現在末尾 [root@localhost ~]# x=${x}789 [root@localhost ~]# echo $x 123456789
4.變量查看
[root@localhost ~]# set
選項:
-u 如果設定此選項,調用未聲明變量時會報錯(默認無任何提示)
[root@localhost ~]# echo $a
[root@localhost ~]#
#上面出現的一個空值,有兩種:一是沒有定義該變量,二是該變量本來就是空值,那我們應該怎麼區分呢?
[root@localhost ~]# set –u [root@localhost ~]# echo $a -bash: a: unbound variable [root@localhost ~]#
5.變量刪除
[root@localhost ~]# unset 變量名 [root@localhost ~]# unset name #上面變量名前不要加取值符$ [root@localhost ~]# unset name [root@localhost ~]# echo $name -bash: name: command not found
三、環境變量
1.環境變量與用戶自定義變量的區別:
環境變量是全局變量,用戶自定義變量是局部變量;也就是說在當前shell和這個shell的所有子shell中都生效,而用戶自定義變量只能是當前shell才能生效
2.設置環境變量
export 變量名=變量值:就是在用戶自定義變量前加一個export
或者
變量名=變量值
export變量名
[root@localhost ~]# export z=1 [root@localhost ~]# bash [root@localhost ~]# pstree sshd---bash---bash—pstree
3.查看環境變量
(1).set
#查看所有變量,包括環境變量
(2).env
#查看環境變量,只查看環境變量
4.調用變量
echo $變量名
5.刪除變量
unset 變量名,注意刪除環境變量需要回到父shell,不允許在子shell中刪除,會提示報錯
[root@localhost ~]# unset $z bash: unset : `1’:not a valid identifier [root@localhost ~]# exit exit [root@localhost ~]# unset $z [root@localhost ~]# pstree --sshd---bash---pstree
變量可以自定義,但是對系統生效的環境變量名和變量作用都是固定的,它們會影響操作系統的操作環境
6.常用系統變量
HOSTNAME:主機名
SHELL:當前shell
TERM:終端環境
HISTSIZE:歷史命令條數
SSH_CLIENT:當前操作環境是用ssh連接的,這裏記錄客戶端ip
#SSH_CLIENT=192.168.0.155 2408 22
SSH_TTY:ssh連接的終端時pts/1
#SSH_TTY=/dev/pts/0
USER: 當前登錄的用戶
#USER=root
區分環境變量和命令:環境變量用大寫,命令全小寫
(1).PATH變量:系統查找命令的路徑
echo $PATH
#查看PATH環境變量
PATH=”$PATH“:/root/sh
#增加PATH變量的值
當我們敲一個命令的時候,可以使用絕對路徑或者相對路徑,但你會發現我們其實都是不敲路徑的,而PATH的作用就是使我們能夠直接使用命令進行運行
[root@localhost ~]# vi hello.sh #/bin/bash echo “shell is beautiful” ~ ~ wq [root@localhost ~]# chmod 755 hello.sh [root@localhost ~]# ./hello.sh shell is beautiful [root@localhost ~]# /root/hello.sh shell is beautiful
現在我想把hello.sh讓它和ls命令一樣可以直接運行:
[root@localhost ~]# cp hello.sh /bin/ [root@localhost ~]# hello.sh #(可以按TabTab補全)
我們可以通過變量疊加來添加環境變量到PATH
[root@localhost ~]# PATH=”@PATH”:/root [root@localhost ~]# echo $PATH [root@localhost ~]# hello.sh shell is beautiful
7.PS1環境變量
PS1變量:命令提示符設置
\d:顯示日期,格式爲”星期 月 日“
\H:顯示完整的主機名。如默認主機名爲”localhost.localdomain“
\t:顯示24小時制時間,格式爲”HH:MM:SS“
\A:顯示24小時制時間,格式爲”HH:MM"
\u:顯示當前用戶名user
\w:顯示當前所在目錄的完整名稱
\W:顯示當前所在目錄的最後一個目錄
\$:提示符。如果是root用戶就會顯示提示符爲"#“,如果是普通用戶會顯示提示符爲”$“
[root@localhost ~]# echo $PS1 [\u@\h \W]\$ [root@localhost ~]# 與[\u@\h \W]\$一一對應
下面我們進行一些修改:
[root@localhost ~]# cd /usr/local/src [root@localhost src]# PS1=’[\u@\A \w]\$ ’ [root@21:22 /usr/local/src]#
上面的提示符設置格式只在當前命令行生效,如果需要永久生效,需要寫入到指定位置
雖然DIY是可以的,但是你會覺得原來的更順眼
[root@21:22 /usr/local/src]# PS1=’[\u@\h \W]\$ ’ [root@localhost src]#
補充:當自己敲一條代碼太長的時候,可以有\來進行換行:
[root@localhost ~]# ls \ > [root@localhost ~]#
8.當前語系查詢及語系變量LANG
locale
#查詢當前系統語系
-LANG:定義系統主語系的變量
-LC_ALL:定義整體語系的變量
echo $LANG
#查看系統當前語系,系統已經生效的語系,重啓後不一定生效
locale –a | more
#查看linux支持的所有語系
cat /etc/sysconfig/i18n
#查詢系統默認語系
[root@localhost ~]# cat /etc/sysconfig/i18n
LANG=”zh_CN.UTF-8”
這格式重啓後仍可以生效的語系
Linux中文支持:
前提條件,正確安裝了中文字體和中文語系,可以有以下結果:
如果有圖形界面,可以正確支持中文顯示
如果有使用第三方遠程工具,只要語系設定正確,可以支持中文顯示
如果使用純字符界面,必須使用第三方插件(如zhcon等)
四、位置參數變量
1.位置參數變量:
位置參數變量 | 作用 |
$n | n爲數字,$0代表命令本身,$1-$9代表從第一到第九個參數,十以上的參數需要用大括號包含,如${10},傳遞需要的值 |
$* | 這個變量代表命令行所有的參數,$*把所有的參數看成一個整體,參數間用空格隔開,但依舊認爲是一個整體 |
$@ | 這個變量也代表命令行所有的參數,不過$@ 把每個參數區分對待 |
$# | 這個變量代表命令行中所有參數的個數 |
例子1:$n功能實現
定義參數:
[root@localhost ~]# mkdir sh [root@localhost ~]# cd sh [root@localhost sh]# ls [root@localhost sh]# touch sum.sh [root@localhost sh]# vi sum.sh #!/bin/bash sum1=$((10+20)) echo $sum1 num1=$1 num2=$2 sum=$(($num1+$num2))
#變量sum的和是num1和num2加起來的和的數值所傳遞過去的
echo $sum
#打印變量sum的值
調用參數:
[root@localhost sh]# chmod 755 sum.sh [root@localhost sh]# ./sum.sh 30 [root@localhost sh]# ./sum.sh 45 67 30 112
#可以在腳本後面添加兩個數直接添加參數值,一般只適用於自己,畢竟自己調用的,第三方#很難知道其功能的使用
例子2:$* ,$@,$*功能實現
#!/bin/bash
echo “A total of $# parameters”
#使用$#代表所有參數的個數
echo “The parameters is: $*”
#使用$*代表所有的參數
echo “The parameters is: $@”
#使用$@也代表所有參數
[root@localhost sh]# touch parameters.sh [root@localhost sh]# vi parameters.sh #!/bin/bash echo “\$* The parameters is: $*” echo “\$@ The parameters is : $@” echo “\$# A total of :$# ” wq [root@localhost sh]# chmod 755 parameters.sh [root@localhost sh]# ./parameters.sh 11 22 33 44 $* The parameter is : 11 22 33 44 $@ The parameters is : 11 22 33 44 S# A total of :4
例子3:$*與$@區別
[root@localhost sh]# touch for.sh [root@localhost sh]# vi for.sh #!/bin/bash for i in “$*”
#$*中所有參數看成一個整體,所以這個for循環只會循環一次
do echo “The parameters is: $i” done for y in “$@” #$@ 中的每個參數都看成是獨立的,所以”$@“中有幾個參數就會循環幾次 do echo “Parameter: $y” done wq [root@localhost sh]# chmod 755 for.sh [root@localhost sh]# ./for.sh 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 [root@localhost sh]#
五、預定義變量
1.預定義變量:
預定義變量 | 作用 |
$? | 最後一次執行命令的返回狀態,如果這個變量的值爲0,證明上一個命令的值正確執行;如果這個變量的值爲非0(具體是哪個數由命令自己決定),則證明上一個命令執行錯誤 |
$$ | 當前進程的進程號(PID) |
$! | 後臺運行的最後一個進程的進程號(PID) |
例子1:區分$?返回值
[root@localhost sh]# ls [root@localhost sh]# echo $? 0 [root@localhost sh]# ls app ls:無法訪問app: 沒有那個文件或目錄 [root@localhost sh]# echo $? 2 [root@localhost sh]# app -bash :app: command not found [root@localhost sh]# echo $? 127
其實返回值0,2,127,$?的返回值由人爲確定的
其實這運用到了shell裏的:&&,||,前者是前面的命令成功,後面才能運行;後者是前面的命令失敗了,後面才能運行。其中運用的就是echo $?,0與非0
[root@localhost sh]# echo $$ 2911 [root@localhost sh]# ps aux | grep 2911 root 2911 0.0 0.1 6824 1720 pts/0 Ss 21:36 0:00 -bash root 3114 0.0 0.0 5960 744 pts/0 S+ 22:36 0:00 grep 2911 [root@localhost sh]# vi bl.sh #!/bin/bash echo “Now : $$” find /root –name hello.sh & echo “houtai : $!” ~ wq [root@localhost sh]# chmod 755 bl.sh [root@localhost sh]# ./bl.sh Now :3137 houtai:3138
#返回的是當前腳本後臺運行時進程的PID,所以是3119而不是2911
#&:後臺符
2.接收鍵盤輸入
read [選項] [變量名]
選項:
-p ”提示信息“:在等待read輸入的時候,輸出提示信息
-t 秒數 :read命令會一直等待用戶輸入,使用此選項可以指定等待時間
-n 字符數:read 命令只接收指定的字符數,就會執行
-s :隱藏輸入的數據,適用於機密信息的輸入
[root@localhost sh]# vi read.sh #!/bin/bash read –p “please input your name: ”-t 30 name echo $name echo –e “\n”#重新打印一下,並自動換行 read –p “please input your age: ”-s age echo –e “\n” read –p “please input your sex[M/F]:”-n 1 sex ~ wq [root@localhost sh]# chmod 755 read.sh [root@localhost sh]# ./read.sh please input your name: DukeZ DukeZ
#允許輸入提示信息
#-t 30的單位是30秒
[
root@localhost sh]# chmod 755 read.sh [root@localhost sh]# ./read.sh please input your name: DukeZ DukeZ please input your age: 20 please input your sex [M/F]: M M
第二部分:Shell編程運算符
一、概述及declare命令
Shell變量缺點:
弱類型
默認字符串型
1.declare命令:
用於聲明變量類型:
[root@localhost ~]# declare [+/-][選項] 變量名
選項:
-:給變量設定類型屬性
+:取消變量的類型屬性
-a:將變量聲明爲數組型
+a:取消聲明變量爲數組型
-i:將變量聲明爲整數型(integer)
-x:將變量聲明爲環境變量
-r:將變量聲明爲只讀變量(read)
-p:顯示指定變量的被聲明的類型
例子:將變量聲明爲數值型
[root@localhost ~]# aa=11 [root@localhost ~]# bb=22 #給aa和bb賦值 [root@localhost ~]# cc=$aa+$bb [root@localhost ~]# echo $cc 11+22 [root@localhost ~]# declare –i cc=$aa+$bb
#聲明變量cc的類型是整數型,它的值是aa和bb的和,不用把aa,bb提前聲明
[root@localhost ~]# echo cc 33 [root@localhost ~]# declare –p -i
2.聲明數組變量
#定義數組
[root@localhost ~]# movie[0]=zp [root@localhost ~]# movie[1]=tp [root@localhost ~]# declare –a movie[2]=live
#查看數組
[root@localhost ~]# echo ${movie} [root@localhost ~]# echo ${movie[2]} [root@localhost ~]# echo ${movie[*]}
例子:
[root@localhost ~]# movie[0]=a [root@localhost ~]# movie[1]=b [root@localhost ~]# declare –a movie[2]=c [root@localhost ~]# echo ${movie}
a#未指定下標的話默認是第一個,即movie[0]
[root@localhost ~]# echo ${movie[2]} c [root@localhost ~]# echo ${movie[*]}
a b c #所有的數組都會顯示
3.聲明環境變量
declare –x test=123
#和export作用相似,但其實是declare命令的作用
聲明成環境變量後才能在子shell內顯示
與export作用類似,但是export是declare –x [變量名]的簡化命令,最終執行的命令其實就是declare命令
4.聲明變量只讀屬性
[root@localhost ~]# declare –r test
#給test賦予只讀屬性,但是請注意只讀屬性會讓變量不能修改不能刪除,甚至不能取消只讀屬性(畢竟不能執行)
例子:
[root@localhost ~]# declare –x test=123 [root@localhost ~]# declare –p test declare –x test=”123” [root@localhost ~]# declare –r test [root@localhost ~]# declare –p test declare –rx test=”123” [root@localhost ~]# test=456 -bash: test: readonly variable [root@localhost ~]# unset test -bash: unset: test: cannot unset: readonly variable [root@localhost ~]# declare +r test -bash: declare: test:readonly variable
二、數值運算方法
方法很多,選擇自己習慣,自己喜歡的就好了。
1.數值運算方法1:
[root@localhost ~]# aa=11 [root@localhost ~]# bb=22
#給aa和bb賦值
[root@localhost ~]# declare –i cc=$aa+$bb
#聲明變量cc的類型是整數型,它的值是aa和bb的和,不用把aa,bb提前聲明
[root@localhost ~]# echo cc 33
2.數值運算方法2:expr或let數值運算工具
[root@localhost ~]# aa=11 [root@localhost ~]# bb=22
#給變量aa和變量bb賦值
[root@localhost ~]# dd=$(expr $aa + $bb)
#dd的值是aa和bb的和。注意“+號左右兩側必須有空格”
[root@localhost ~]# echo dd 33 [root@localhost ~]# ee=$(expr $aa+$bb) [root@localhost ~]# echo ee 11+22
#注意要用空格隔開“+”左右兩邊
3.數值運算方法3:“$((運算式))”或“$[運算式]”
[root@localhost ~]# aa=11 [root@localhost ~]# bb=22
#給變量aa和變量bb賦值
[root@localhost ~]# ff=$(($aa+$bb)) 33 [root@localhost ~]# gg=$[$aa+$bb] 33
#這裏的$[]會和後面的條件測試語句混淆,建議使用雙小括號
#hh=$()是吧括號裏的結果賦值給hh
[root@localhost ~]# hh=$(date) [root@localhost ~]# echo hh 2015年 08月 02日 星期日 13:26:34 CST [root@localhost ~]# ii=date [root@localhost ~]# echo $ii date
4.運算符:
優先級 | 運算符 | 說明 |
13 | -,+ | 單目負、單目正 |
12 | !,` | 邏輯非、按位取反或補碼 |
11 | * , / , % | 乘、除、取模 |
10 | + , - | 加、減 |
9 | << , >> | 按位左移、按位右移 |
8 | <=,>=,<,> | 小於或等於、大於或等於、小於、大於 |
7 | == , != | 等於、不等於 |
6 | & | 按位與 |
5 | ^ | 按位異或 |
4 | | | 按位或 |
3 | && | 邏輯與 |
2 | || | 邏輯或 |
1 | = , += , *= , /= , %= , &= , `= , |= , <<= , >>= | 賦值、運算且賦值 |
注:這裏是優先級數值高的優先級高
例子:
[root@localhost ~]# aa=$(((11+3)*3/2)) [root@localhost ~]# echo $aa 21
#雖然乘和除的優先級高於加,但是通過小括號可以調整運算符優先級
[root@localhost ~]# bb=$((14%3)) [root@localhost ~]# echo $bb 2
#14不能被3整除,餘數是2
[root@localhost ~]# cc=$((1&&0)) [root@localhost ~]# echo $cc 0
#邏輯與運算只有相與的兩邊都是1,與的結果纔是1,否則與的結果是0(同1爲1)
[root@localhost ~]# dd=$((1||0)) [root@localhost ~]# echo dd 1
#邏輯或只要有1,或的結果就是1(有1爲1)
三、變量測試
通用度不高,只應用與Shell,格式比較複雜,但是語法簡單
變量置換方式 | 變量y沒有設置 | 變量y爲空值 | 變量y設置值 |
x=${y-新值} | x=新值 | x爲空 | x=$y |
x=${y:-新值} | x=新值 | x=新值 | x=$y |
x=${y+新值] | x爲空 | x=新值 | x=新值 |
x=${y:+新值} | x爲空 | x爲空 | x=新值 |
x=${y=新值} | x=新值 y=新值 | x爲空 y值不變 | x=$y y值不變 |
x=${y:=新值} | x=新值 y=新值 | x=新值 y=新值 | x=$y y值不變 |
x=${y?新值} | 新值輸出到標準錯誤輸出(屏幕) | x爲空 | x=$y |
x=${y:?新值} | 新值輸出到標準錯誤輸出(屏幕) | 新值輸出到標準錯誤輸出(屏幕) | x=$y |
變量測試在腳本優化時使用,程序壓力小,用PHP追求效率,但是會比較複雜,但是shell適用於自動化,需要邏輯簡單
例子1:測試x=${y-新值}
[root@localhost ~]# unset y #刪除變量y [root@localhost ~]# x=${y-2} #進行測試 [root@localhost ~]# echo x 2 #因爲變量y不存在,所以x=new [root@localhost ~]# y=”” [root@localhost ~]# set … y= [root@localhost ~]# x=${y-2} [root@localhost ~]# echo $x #也是空值 [root@localhost ~]# y=1 [root@localhost ~]# x=${y-2} [root@localhost ~]# echo x 1
測試命令能看懂即可,瞭解就可以了