目錄
1.shell腳本的執(zhí)行方法 2.shell的變量類型 3.shell特殊變量
4.變量子串的常用操作 5.批量修改文件名實踐 6.變量替換
7.在shell中計算字符串長度的方法 8.變量的數(shù)值計算:(()) 的用法
9. 變量的數(shù)值計算:let的用法 10.變量的數(shù)值計算:exPR的用法
11.變量的數(shù)值計算:bc的用法 12.條件測試的多種方法
13.字符串測試操作符 14.整數(shù)二元比較操作符
15.邏輯操作符 16.利用shell知識制作單級及多級菜單
17.case結(jié)構(gòu)條件語句 18. 當型循環(huán)和直到型循環(huán)
19.for循環(huán)
待續(xù)。。。
當shell腳本以非交互的方式運行時,它會先查找環(huán)境變量ENV,該變量指定了一個環(huán)境文件(通常是.bashrc),然后從該環(huán)境變量文件開始執(zhí)行,當讀取了ENV文件后,SHELL才開始執(zhí)行shell腳本中的內(nèi)容。
shell腳本的執(zhí)行通常可以采用以下三種方法:
bash script-name 或者 sh script-namepath/script-name 或者 ./script-name(當前路徑下執(zhí)行)source script-name 或 . script-name(注意符號“.”與 script-name之間有空格)第一種方法是腳本文件本身沒有可執(zhí)行權(quán)限時,通常使用的方法;
第二種方法需要先將腳本文件的權(quán)限改為可執(zhí)行,然后通過腳本路徑就可以直接執(zhí)行;
第三中方法是在當前shell環(huán)境中直接執(zhí)行,而不是新創(chuàng)建一個子shell,當我們需要在一個腳本中使用另一個腳本中的變量的時候就使用第三種方法,例如創(chuàng)建如下腳本,其中定義了chars變量:

通過上面三種方法執(zhí)行:

可以看出方法1,2執(zhí)行腳本是系統(tǒng)會自動新創(chuàng)建一個子shell,執(zhí)行之后,其變量不會在當前shell有效,而第三種方法是告訴系統(tǒng)讓這個腳本直接在當前shell執(zhí)行,顯然其定義的變量chars在當前shell中也是有效的,所以需要在某個腳本中使用另外一個腳本中的變量時,需要使用第3中方法執(zhí)行腳本。
shell中的變量分為環(huán)境變量和全局變量
環(huán)境變量也稱為全局變量,可以在創(chuàng)建他們的shell及其派生的任意子進程shell中使用。局部變量只能使用在創(chuàng)建它們的shell函數(shù)或腳本中使用。
環(huán)境變量用于定義Shell的運行環(huán)境,保證shell命令的正確執(zhí)行,shell通過環(huán)境變量來確定登錄用戶名,命令路徑,終端類型,登錄目錄。環(huán)境變量可以在命令行中設(shè)置,但用戶退出時這些變量值也會丟失,因此最好在用戶家目錄下的.bash_ptofile文件會全局配置/etc/profile文件或者/etc/profile.d中定義,將環(huán)境變量放入profile中,每次用戶登錄,這些變量值都將被初始化。
傳統(tǒng)上,所有環(huán)境變量均為大寫。環(huán)境變量用于用戶進程前,必須用export命令導出。
有一些環(huán)境變量,比如HOME,PATH,SHELL,UID,USER等在用戶登錄之前就已經(jīng)被/bin/login程序設(shè)置了,通常環(huán)境變量的定義并保存在用戶的家目錄下的./bash_profile文件中。
已經(jīng)定義的變量可以用unset在取消定義。
本地變量定義的三種方式:
var_name=value
var_name='value'
var_name="value"
下面看看這三種方式的區(qū)別

第一種方法是直接定義變量內(nèi)容,但是內(nèi)容必須連續(xù),中間不能有空格字符;
接著看下面:

第二種方法通過單引號定義變量,只會原樣輸出字符串內(nèi)容,而不會對字符串中的變量和特殊字符進行解析,適合定義單純字符顯示;
第一種和第三種,輸出時,會對內(nèi)容進行解析,輸出解析后的內(nèi)容,有于第一種方法不能定義不連續(xù)的變量,所以通常在需要解析的時候都加上雙引號,而很少使用第一種方法,第一種方法一般僅僅用來定義連續(xù)的數(shù)字或者路徑。
位置變量
進程狀態(tài)變量
| 編號 | 表達式 | 說明 | 
| 1 | ${#string} | 返回$string的長度 | 
| 2 | ${string:position} | 在$string中,從位置position之后開始提取子串 | 
| 3 | ${string:position:length} | 在 | 
| 4 | ${string#substring} | 從變量 | 
| 5 | ${string##substring} | 從變量 | 
| 6 | ${string%substring} | 從變量 | 
| 7 | ${string%%substring} | 從變量 | 
| 8 | ${string/substring/replace} | 使用 | 
| 9 | ${string//substring/replace} | 使用 | 
| 10 | ${string/#substring/replace} | 如果 | 
| 11 | ${string/%substring/replace} | 如果 | 
舉例說明如下:

例如有下面的文件:

現(xiàn)在想要將后綴前部改為大寫JPG:
方法一:
#!/bin/bashfor obj in $(ls *.jpg)do    mv ${obj} $(echo ${obj/%jpg/JPG})done方法二:
rename 's/jpg$/JPG/' *.jpg 
 
6.變量替換 返回目錄
| 運算符號 | 作用 | 
| ${value:-Word} | 如果變量名存在且非null,返回變量值;否則,返回word字符串 用途:如果變量未定義,則返回默認值 | 
| ${value:=word} | 如果變量名存在且非null,返回變量值;否則,設(shè)置這個變量值為word 用途:如果變量未定義,,則設(shè)置變量為默認值,并返回默認值 | 
| ${value:?"not defined"} | 如果變量名存在且非null,返回變量值;否則顯示“not defined”,并退出當前命令或腳本。 用途:用于捕捉由于變量未定義而導致的錯誤,并退出程序。 | 
| ${value:+word} | 如果變量名存在且非null,返回word,否則返回null。 用途:測試變量是否存在。 | 
示例如下:

建立一個字符串:

注意:使用 wc -m 的方法會計算換行符,因為echo會在輸出完字符串之后自動加上一個換行符,使用echo -n 會去掉換行符:
 
比較上面三種方法的效率:

time :
獲取一個程序的執(zhí)行時間,可以獲取到實際運行時間以及程序在用戶態(tài)和內(nèi)核態(tài)分別的時間,大部分的性能測試,可能只需要關(guān)注實際(real)時間
看到上面三種獲取字符串長度的速度相差幾十倍到上百倍,一般調(diào)用外部命令處理,與內(nèi)置功能性能相差很大。所以在shell編程,盡量使用內(nèi)置操作或函數(shù)完成。
(1) (())用法:(此法很常用,且效率高)
用于執(zhí)行的整數(shù)運算,支持的運算符與C語言中的基本一致,除了特別注意 "**" 在 (()) 中表示冪運算,而C語言不支持,如 ((2**3)) 結(jié)果是 8.
示例:

注意:1)**表示冪運算
2)上面涉及的變量元素必須為整型,不能是小數(shù)和字符,涉及小數(shù)的后面使用 bc 可以實現(xiàn)。

 (()) 內(nèi)部的變量可以不用加

各種shell運算的腳本例子:


實踐:用shell腳本編寫一個實現(xiàn)加,減,乘,除的計算器:


與 ((表達式)) 功能一致,但是沒有 (()) 的計算效率高,所以常用 (()),而不去使用let.

expr命令一般用于整數(shù)計算,但也可用于字符串,用來求表達式變量的值,同時expr也是一個手工命令計算器。


expr 的語法不是很好,所以不常用,這里標記,保證看到別人使用的時候,自己能夠看懂。
下面介紹expr比較好用兩個技巧
1)檢查某個文件是否是某一類型或擴展名:
  
2)判斷一個變量是否是整數(shù):
  
寫出判斷一個輸入是否為整數(shù)的腳本:
  
  
bc支持科學計算
  
使用shell編寫輸出楊輝三角的腳本:
#!/bin/bashexport%20LANG="zh_CN.GB18030"#本文內(nèi)容來自《老男孩linux運維實戰(zhàn)培訓中心》shell%20編程部分學生練習資料#如果腳本后面沒有參數(shù),提示輸入一個參數(shù)if%20(%20test%20-z%20$1%20);then%20%20%20%20read%20-p%20"Input%20max%20int%20lines:"%20MAX%20else%20%20%20%20MAX=$1fi#判斷參數(shù)的合法性#將參數(shù)中的數(shù)字全部替換為空,然后判斷替換后的內(nèi)容是否為空#若不為空,表明參數(shù)中含有非數(shù)字的其他非數(shù)字內(nèi)容,則不合法#“[%20]”的功能與test一致,可以%20man%20test%20查看[%20-n%20"$(echo%20${MAX}|sed%20's/[0-9]//g')"%20]%20&&%20/echo%20"The%20number%20you%20input%20must%20be%20int(1-9)"%20&&%20exit%201#將輸入限制在小于10[%20!%20${MAX}%20-lt%2010%20]%20&&%20/echo%20"The%20number%20you%20input%20must%20be%20int(1-9)"%20&&%20exit%201#starta[0]=1for%20((i=0;i<MAX;i++))do%20%20%20%20for%20((j=$i;j>0;j--))%20%20%20%20do%20%20%20%20%20%20%20%20((a[$j]+=a[$j-1]))%20%20%20%20done%20%20%20%20for%20((j=0;j<=MAX-i;j++))%20%20%20%20do%20%20%20%20%20%20%20%20if%20((MAX<=6));then%20%20%20%20%20%20%20%20%20%20%20%20echo%20-en%20"/t"%20%20%20%20%20%20%20%20else%20%20%20%20%20%20%20%20%20%20%20%20echo%20-n%20"%20%20%20%20"%20%20%20%20%20%20%20%20fi%20%20%20%20done%20%20%20%20for%20((j=0;j<=i;j++))%20%20%20%20do%20%20%20%20%20%20%20%20if%20[%20${MAX}%20-le%206%20];then%20%20%20%20%20%20%20%20%20%20%20%20echo%20-en%20"/t/t"${a[$j]}%20%20%20%20%20%20%20%20else%20%20%20%20%20%20%20%20%20%20%20%20echo%20-en%20${a[$j]}%20%20%20%20%20%20%20%20fi%20%20%20%20doneechodone
運行結(jié)果:
12.條件測試的多種方法 返回目錄
語法格式:
格式1:test expression
格式2:[ expression ]
格式3:[[ 測試表達式 ]]
注:中括號與表達式之間前后都有空格
格式1與格式2是等價的;格式3為擴展的test命令,在 [[ ]] 中可以使用通配符進行模式匹配,如&&,||,>, <等操作符可以應(yīng)用于[[ ]]中,但不能應(yīng)用于[ ]中;對整數(shù)的關(guān)系運算,也可以使用Shell的算術(shù)運算符 (()).
關(guān)于各種測試操作符只需要在終端man test 即可得到詳細描述:
| 常用的文件測試操作符號 | 說明 | 
| -f file | 若文件存在且為普通文件則真 | 
| -d file | 若文件存在且為目錄則真 | 
| -s file | 若文件存在且不為空(文件大小非0)則真 | 
| -e file | 若文件存在則真,區(qū)別于-f | 
| -r file | 若文件存在且可讀則真 | 
| -w file | 若文件存在且可寫則真 | 
| -x file | 若文件存在且可執(zhí)行則真 | 
| -L file | 若文件存在且為鏈接文件則真 | 
| f1 -nt f2 | 若文件f1 比文件 f2 新則真 | 
| f1 -ot f2 | 若文件f1 比文件 f2 舊則真 | 
字符串測試操作符的作用:比較兩個字符串是否相同、字符串長度是否為0,字符串是否為null等
  “=”比較兩個字符串是否相同,與 “==”等價,如 if [ "
| 常用字符串測試操作符 | 說明 | 
| -z "string" | 若string長度為0,則真 | 
| -n "string" | 若string長度步為0,則真 | 
| “string1”= ”string2“ | 若string1等于string2則真,可以使用“==”代替“=” | 
| “string1”!= ”string2“ | 若string1不等于string2則真 | 
注意:測試符“==”,“=”,“!=”好前后均需與測試字符串之間留空格!!!

| 在[ ]中使用的比較符 | 在(())和[[]]中使用的比較符 | 說明 | 
| -eq | == | 相等 | 
| -ne | != | 不等 | 
| -gt | > | 大于 | 
| -ge | >= | 大于或等于 | 
| -lt | < | 小于 | 
| -le | <= | 小于或等于 | 

| 在[]中的使用 | 在[[]]中的使用 | 說明 | 
| -a | && | 與,兩端均為真則真 | 
| -o | || | 或,兩端有一個為真則真 | 
| ! | ! | 非,相反則真 | 
 

語法:
case "字符串變量" in
值1)指令1...
;;
值2)指令2...
;;
*)指令
;;
esca
給字符串顯示不同的顏色:
shell腳本中echo可以顯示不同顏色的字符,格式如下:
格式如下(參考http://www.cnblogs.com/wish123/p/4131825.html): echo -e "/033[字背景顏色;文字顏色m字符串/033[0m" 例如: echo -e "/033[41;36m something here /033[0m" 其中41的位置代表底色, 36的位置是代表字的顏色 1、字背景顏色和文字顏色之間是英文的";" 2、文字顏色后面有個m 3、字符串前后可以沒有空格,如果有的話,輸出也是同樣有空格

下面利用case來該給定的字符串加上不同的顏色:
%201%20#!/bin/bash%202%20#Paint%20given%20chars%20with%20given%20color%203%20usage="Usage:chars%20{black|red|green|yellow|blue|purple|white}"%204%20%20[[%20$#%20-ne%202%20]]%20&&{%20%205%20%20%20%20%20%20echo%20"${usage}"%20%206%20%20%20%20%20%20exit%201%207%20}%208%20BLACK="/033[1;30m";%20RED="/033[1;31m"%20;GREEN="/033[1;32m";%20YELLOW="/033[1;33m"%209%20BLUE="/033[1;34m";%20PRUPLE="/033[1;35m";%20WHITE="/033[1;37m"10%20COLOR_END="/033[0m"11%2012%20chars=$113%20selected_color=$214%2015%20case%20${selected_color}%20in16%20%20%20%20%20black)%20res=${BLACK}17%20;;18%20%20%20%20%20red)%20res=${RED}19%20;;20%20%20%20%20%20green)%20res=${GREEN}21%20;;22%20%20%20%20%20yellow)%20res=${YELLOW}23%20;;24%20%20%20%20%20blue)%20res=${BLUE}25%20;;26%20%20%20%20%20purple)%20res=${PURPLE}27%20;;28%20%20%20%20%20white)%20res=${WHITE}29%20;;30%20%20%20%20%20*)%20echo%20'Input%20color%20is%20not%20supported'31%20%20%20%20%20%20%20%20echo%20${usage}32%20%20%20%20%20%20%20%20exit%20133%20;;34%20esac35%2036%20echo%20-e%20"${res}"$1"${COLOR_END}"![]()
![]()
18. 當型循環(huán)和直到型循環(huán)  返回目錄
 
while條件語句,條件滿足一直執(zhí)行command
while condition    do    commanddone 
until語法,條件滿足就退出,目前很少用,作為了解
until condition    do    commanddone 
![]()
#!/bin/bashi=10while%20(($i>=1))do%20%20%20%20echo%20$i%20%20%20%20((i--))done![]()
 
![]()
使用until實現(xiàn)上面同樣的功能:
![]()
#!/bin/bashi=10until%20[%20$i%20-eq%200%20]%20do%20%20%20%20echo%20$i%20%20%20%20((%20i--%20))done![]()
 在實踐中經(jīng)常需要使用while來處理日志文件,下面實際中使用while讀取文本的方法:
![]()
#1exec%20<FILEwhile%20read%20linedo%20%20%20%20cmddone#2cat%20${FILE}%20|%20while%20read%20linedo%20%20%20%20cmddone#3while%20read%20linedo%20%20%20%20cmddone<FILE![]()
 
19.for循環(huán) 返回目錄
 
for循環(huán)語法結(jié)構(gòu)1:
![]()
for%20var%20in%20var_listdo%20%20%20%20cmd1%20%20%20%20cmd2%20%20%20%20...done![]()
 
在此結(jié)構(gòu)中,%20“in%20var_list”可以省略,省略時,相當于in%20"@",例如fori就相當于foriin" @",例如fori就相當于foriin"@".
for循環(huán)語法結(jié)構(gòu)2:
![]()
for%20((exp1;exp2;exp3))%20#與C語言一樣do%20%20%20%20cmd1%20%20%20%20cmd2%20%20%20%20...done![]()
#!/bin/bashfor%20i%20in%2010%209%208%207%206%20do%20%20%20%20echo%20$idone![]()
下面代碼實現(xiàn)同樣的功能:
#!/bin/bashfor i in {10..6}do    echo $idone 
#!/bin/bashfor i in $(seq -s " " 10 -1 6)do    echo $idone 
獲取當前目錄下的所有文件名,打印
#!/bin/bashfor i in $(ls) do    echo $idone 
打印9*9乘法表:
![]()
%201%20#!/bin/bash%202%20for%20a%20in%20$(%20seq%201%209%20)%203%20do%204%20%20%20%20%20for%20b%20in%20$(%20seq%201%209%20)%205%20%20%20%20%20do%20%20%206%20%20%20%20%20%20%20%20%20if%20[%20$a%20-ge%20$b%20];then%207%20%20%20%20%20%20%20%20%20%20%20%20%20echo%20-en%20"$a%20x%20$b%20=%20$((a*b))%20%20"%208%20%20%20%20%20%20%20%20%20fi%20%20%209%20%20%20%20%20done10%20echo%20"%20"11%20done12%2013%20echo![]()
![]()
 
| 
 
 | 
新聞熱點
疑難解答