認識Shell
Shell原意為貝殼
Linux系統中的shell是一個特殊的應用程序,它介于操作系統內核與用戶之間,充當一個“命令解釋器”的角色,負責接收用戶輸入的操作指令(命令)并進行解釋,將需要執行的操作傳遞給內核執行,并輸出執行結果。
可以使用命令查看當前使用的是哪種shell以及當前Linux系統中都支持哪些shell種類。
查看當前系統使用的shell
查看當前Linux系統所支持的shell種類
其中/bin/bash是目前大多數Linux版本采用的默認shell。Bash的全稱為Bourne Again Shell,是最受歡迎的開源軟件項目之一。
常見的shell解釋器程序有很多種,使用不同的shell時,其內部指令、命令行提示等方面會存在一些區別。
Shell腳本
只要將平時使用的各種Linux命令按順序保存到一個文本文件,然后添加可執行權限,這個文件就成為一個shell腳本了。
編寫一個恰到好處的shell腳本程序,可以批量處理、自動化地完成一系列維護任務、大大減輕管理員的負擔。
周期性的任務可以通過Crond服務來管理,而步驟復雜、操作繁瑣的任務可以使用Shell腳本來批量處理,兩相結合就可以非常靈活、自主地完成各種系統運維工作。Shell腳本負責具體的備份操作,Crond服務負責控制備份周期。
1、腳本的編寫
Shell腳本主要由開頭部分、注釋部分以及語句部分組成
1)開頭
“#!/bin/bash”是一行特殊的腳本聲明,表示此行以后的語句通過/bin/bash程序來解釋執行。
符號“#!”用來告訴系統它后面的參數是用來執行該文件的程序。
2)注釋
其它以”#”開頭的語句表示注釋信息,建議在程序中使用注釋,即使過了長時間也能很快的了解腳本的用途。
3)語句
Linux各種命令的集合
2、腳本的執行
編寫完成shell腳本后,需要賦予執行權限
執行此腳本文件后,輸出結果與依次執行這兩條命令是相同的,從而實現了“批量處理“的自動化過程。
Linux還提供了執行shell腳本的方式——指定某個shell來解釋腳本語句,或者通過內部命令source(或點號”.”)來加載文件的源代碼執行。
例如,使用”sh first.sh”或“. first.sh”都可以執行firsh.sh腳本中的語句。
注意:以上三種執行方式不添加執行權限也可以執行文件
3、腳本調試
bash -n /path/to/scriptfile 檢測腳本中的語法錯誤
bash -x /path/to/scriptfile 調試執行
Shell變量
Shell變量用來存放系統和用戶需要使用的特定參數(值)。而且這些參數可以根據用戶的設定或系統環境的變化而相應變化。
常見的Shell變量的類型包括自定義變量、環境變量、預定義變量、位置變量。
1、自定義變量
自定義變量是由系統用戶自己定義的變量,只在用戶自己的Shell環境中有效,因此又稱為本地變量。
1)定義新的變量
定義變量的基本格式為”變量名=變量值“,等號兩邊沒有空格。
[root@localhost ~]# name=tom
[root@localhost ~]# age=20
變量名稱命名規則:
a.不能使程序中的保留字:例如if, for
b.只能使用數字、字母及下劃線,且不能以數字開頭
c.見名知義
d.統一命名規則:駝峰命名法
2)查看和引用變量的值
2、環境變量
環境變量指的是出于運行需要而由Linux系統提前創建的一類變量,主要用于設置用戶的工作環境,包括用戶宿主目錄、命令替換路徑、用戶當前目錄、登錄終端等。環境變量的值由linux系統自動維護,會隨著用戶狀態的改變而改變。
使用env命令可以查看當前工作環境下的環境變量,對于常見的一些環境變量應了解其各自的用途。
例如USER表示用戶標識、HOME表示用戶的宿主目錄、LANG表示語言和字符集、PWD表示當前所在的工作目錄、PATH表示命令搜索路徑….
查看當前Linux系統中所有的環境變量
可以用命令修改環境變量的搜索路徑,這樣寫完shell腳本以后可以直接輸入腳本名稱直接執行,不用每次輸入文件的路徑。
臨時修改:只對當前終端有效
永久修改:永久有效
修改家目錄下的隱藏文件.bash_profile,添加指定的搜索路徑即可,搜索路徑之間用“:”分隔,添加完成后需要重新讀取該配置文件讓其生效。
重新讀取配置文件使其立即生效
將搜索路徑添加完成后直接輸入文件名即可運行成功
PATH的搜索順序:從左到右依次搜索,
同樣在/usr/bin下面寫一個同名的腳本文件,執行時依然執行/testdir/script目錄下的文件,當把hash緩存清空后,即執行了/usr/bin目錄下的first.sh文件,如果把緩存再次清空,執行腳本文件報錯,清空緩存后,有可以執行了。
從此可見,緩存(hash)中的命令優先于搜索路徑,如果緩存中有這條命令,就不去搜索PATH變量,文件不存在也執行hash,會報錯;清空緩存后,按照PATH變量的搜索順序依次查找,當PATH變量有多個可以匹配,執行先匹配到,匹配到第一個腳本時不再往下搜索。
環境變量的配置文件
全局配置文件:/etc/.bash_profile
個人配置文件:~/.bash_profile
3、預定義變量
預定義變量是由Bash程序預先定義好的一類特殊變量,用戶只能使用預定義變量,而不能創建新的預定義變量,也不能直接為預定義變量賦值。預定義變量使用$符號和另一個符號組合表示,較常用的幾個預定義變量如下:
$#:表示命令行中位置參數的個數。
$*:傳遞給腳本的所有參數,全部參數合為一個字符串。
$@: 傳遞給腳本的所有參數,每個參數為獨立字符串
$@ $* 只在被雙引號包起來的時候才會有差異
$?:表示前一條命令執行后的返回狀態,0表示成功,非0表示失敗。
$0:表示當前執行的腳本或程序的名稱。
示例:備份目錄數據,并顯示備份信息
4、位置變量
位置變量:位置變量也稱為位置參數,在腳本代碼中調用通過命令行傳遞給腳本的參數
當執行命令行操作時,第一個字符表示命令名或腳本程序名,其余的字符串參數按照從左到右的順序依次賦值給位置變量。
$1, $2, …:對應第1、第2等參數, shift [n]換位置
示例:計算兩個數值的和
示例:判斷給出的文件的行數
定義只讀變量
只讀變量:只能聲明,但不能修改和刪除
readonly name
declare -r name
示例:定義只讀變量
注意:只讀變量同樣只在當前終端中有效
變量賦值的特殊操作
1)雙引號(”)
雙引號主要起了一個界定字符串的作用,特別是當要賦值的內容中包含空格時,必須以雙引號括起來,否則會報錯;其他情況下雙引號通??梢允÷浴?/span>
在雙引號范圍內,使用“$”符號可以引用其他變量的值(變量引用),從而能夠直接調用現有變量的值來賦值給新的變量。
2)單引號(’)
當要賦值的內容中包含$、”、 \等具有特殊含義的字符時,應使用單引號括起來。在單引號的范圍內,將無法引用其他變量的值,任何字符均作為普通字符看待。但賦值內容中包含單引號時,需使用“\’”符號進行轉義,以免沖突。
3)反撇號(`)
反撇號主要用于命令替換,允許將執行某個命令的屏幕輸出結果賦值給變量。反撇號括起來的范圍內必須是能夠執行的命令行,否則將會出錯。
需要注意的是,使用反撇號難以在一行命令中實現嵌套命令替換操作,這時可以改用“$()”來代替反撇號操作,以解決嵌套的問題。
變量的作用范圍
1、設置局部變量
默認情況下,新定義的變量只在當前的Shell環境中有效,因此成為局部變量。當進入子程序或新的子Shell環境時,局部變量將無法再使用。
2、設置全局變量
為了使用戶定義的變量在所有的子Shell環境中能夠繼續使用,減少重復設置工作,可以通過內部命令export將指定的變量導出為”全局變量“可以同時制定多個變量名稱作為參數(不需使用$符合),變量名之間以空格分隔。
使用export導出全局變量的同時,也可以為變量進行賦值,這樣在新定義全局變量時就不需要提前進行賦值了,也可以將之前的局部變量設置使用export命令設置為全局變量,使其在子shell中可以調用。
注意:設置全局變量后,子進程可以調用父進程的變量,反之則不可以。
條件測試
使用專門的測試工具test命令,可以對特定條件進行測試,并根據返回值來判斷條件是否成立(返回值0表示條件成立)。
test 條件表達式
或
[ 條件表達式 ]
兩種方式作用完全相同,但后者更為常用,也更貼近編程習慣。需要注意的是,方括號與表達式之間需要至少一個空格進行分割。
根據需要測試的條件類別不同,條件表達式也不一樣。比較常用的條件操作包括文件測試、整數值比較、字符串比較,以及針對多個條件的邏輯測試。
執行條件測試操作后,通過預定義變量”$?“可以獲得測試命令的返回狀態值,從而判斷該條件是否成立。echo $?查看返回狀態值。
1、文件測試
存在性測試
-e FILE: 文件存在性測試,存在為真,否則為假
-a FILE:同-e
存在性及類別測試
-b FILE: 是否存在且為塊設備文件
-c FILE: 是否存在且為字符設備文件
-d FILE: 是否存在且為目錄文件
-f FILE: 是否存在且為普通文件
-h FILE 或 -L FILE:存在且為符號鏈接文件
-p FILE: 是否存在且為命名管道文件
-S FILE: 是否存在且為套接字文件
文件權限測試
-r: 測試當前用戶是否有權限讀?。?/span>Read)
-w: 測試當前用戶是否有權限寫入(Write)
-x: 測試是否這只有可執行權限(Excute)
文件特殊權限測試
-g FILE:是否存在且擁有sgid權限
-u FILE:是否存在且擁有suid權限
-k FILE:是否存在且擁有sticky權限
文件大小測試
-s FILE: 是否存在且非空;
文件是否打開
-t fd: fd表示文件描述符是否已經打開且與某終端相關
-N FILE:文件自動上一次被讀取之后是否被修改過
-O FILE:當前有效用戶是否為文件屬主
-G FILE:當前有效用戶是否為文件屬組
雙目測試
FILE1 -ef FILE2: FILE1與FILE2是否指向同一個設備上的相同inode
FILE1 -nt FILE2: FILE1是否新于FILE2
FILE1 -ot FILE2: FILE1是否舊于FILE2
2、數值比較
-eq: 第1個數等于(Equal)第2個數
-ne: 第1個數不等于(Not Equal)第2個數
-gt: 第1個數大于(Greater Than)第2個數
-lt: 第1個數小于(Lesser Than)第2個數
-le: 第1個數小于或等于(Lesser or Equal)第2個數
-ge: 第1個數大于或等于(Lesser or Equal)第2個數
3、字符串比較
=: 第1個字符串與第2個字符串相同
!=: 第1個字符串與第2個字符串相同,其中!符號表示取反的意思
-z: 檢查字符串是否為空(Zero),對于未定義或賦予空值的變量將視為空串。
==: 是否等于;
>: ascii碼是否大于ascii碼
<: 是否小于
!=: 是否不等于
=~: 左側字符串是否能夠被右側的PATTERN所匹配
注意: 此表達式一般用于[[ ]]中;
-z "STRING":字符串是否為空,空為真,不空為假
-n "STRING":字符串是否不空,不空為真,空為假
注意:用于字符串比較時的用到的操作數都應該使用引號
算術運算
bash中的算術運算
+, -, *, /, %取模(取余) , **(乘方)
實現算術運算:
let var=算術表達式
var=$[算術表達式]
var=$((算術表達式))
var=$(expr arg1 arg2 arg3 …)
declare –i var = 數值
echo ‘算術表達式’ | bc
乘法符號有些場景中需要轉義, 如*
bash有內建的隨機數生成器: $RANDOM( 1-32767)
echo $[$RANDOM%50] : 0-49之間隨機數
賦值
增強型賦值:
+=, -=, *=, /=, %=
let varOPERvalue
例如:let count+=3 自加3后自賦值
自增,自減:
let var+=1
let var++
let var-=1
let var–
示例:算術運算
示例:j自增自減運算
邏輯測試
&&:邏輯與,表示“而且”的意思,只有當前后兩個條件都成立時,真個測試命令的返回值才為0。使用test命令測試時,&&可改為-a。
||:邏輯與,表示“或者”的意思,只有前后兩個條件有一個成立時,整個測試命令的返回值為0。使用test名測試時,||可改為-o。
!:邏輯否,表示“不”的意思,只有當指定的條件不成立時,正測試命令的返回值才為0。
邏輯運算
true, false
1, 0
與:&&
1 與 1 = 1
1 與 0 = 0
0 與 1 = 0
0 與 0 = 0
或:||
1 或 1 = 1
1 或 0 = 1
0 或 1 = 1
0 或 0 = 0
非: !
! 1 = 0
! 0 = 1
短路運算
短路與:
第一個為0,結果必定為0;
第一個為1,第二個必須要參與運算;
短路或:
第一個為1,結果必定為1;
第一個為0,第二個必須要參與運算;
異或: ^
異或的兩個值,相同為假,不同為真
聚集命令
有兩種聚集命令的方法
復合式: date; who | wc –l 命令會一個接一個地運行
子shell: (date; who | wc -l ) >> /tmp/trace
所有的輸出都被發送給單個STDOUT和STDERR
組合測試條件
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如: [ -e FILE ] && [ -r FILE ]
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行;
# [ -z “$HOSTNAME” -o $HOSTNAME "==\"localhost.localdomain" ] && hostname www.magedu.com
# [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
示例:判斷兩個變量的大小
退出狀態
進程使用退出狀態來報告成功或失敗,$? 變量保存最近的命令退出狀態
0 代表成功
1-255 代表失敗
示例:ping一個ip地址,并查看其返回值
退出狀態碼
bash自定義退出狀態碼
exit [n]:自定義退出狀態碼;
注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的狀態碼
示例:根據測試條件返回狀態碼
read命令:接受用戶輸入
使用read來把輸入值分配給一個或多個shell變量:
read [選項] [參數]
-p 指定要顯示的提示信息
-t 指定讀取值時等待的時間(秒)
-n 讀取用戶輸入的前幾個字符
-s 隱藏用戶的輸入字符
-r 允許輸入包含反斜杠
-d 以-d選項指定的字符作為結束符,如空格、特殊符號
read 從標準輸入中讀取值,給每個單詞分配一個變量,所有剩余單詞都被分配給最后一個變量。
read -p “Enter a filename: “ FILE
示例:編寫修改當前用戶的密碼腳本
使用-s選項可隱藏用戶要輸入的字符信息,如密碼等信息
原創文章,作者:cyh5217,如若轉載,請注明出處:http://www.www58058.com/33473
學習態度端正,博客不僅寫的完善而且有自己的想法,通過自己的思路匯總,足以見其對知識的理解深刻,望后期能持續學習,提升自我。