Shell腳本簡介:
Shell腳本是一種特殊的程序,它是用戶與linux系統內核之間的一個接口,shell是一個工具程序,在用戶登錄后系統啟動。它解釋并運行由命令行或腳本文件輸入的命令,從而實現用戶與內核間的交互。
Shell腳本:也就是用各類命令預先放入到一個文件中,方便一次性執行的一個程序文件,主要是方便管理員進行設置或者管理用的,是利用shell的功能所寫的一個程序,這個程序是使用純文本文件,將一些shell的語法與指令寫在里面,然后用正規表示法,管道命令以及數據流重導向等功能,以達到我們所想要的處理目的
程序:指令+ 數據
程序編程風格:
過程式:以指令為中心,數據服務于指令
對象式:以數據為中心,指令服務于數據
shell 程序:提供了編程能力,解釋執行
程序的執行方式:
計算機:運行二進制指令;
編程語言:
低級:匯編
高級:
編譯:高級語言–> 編譯器–> 目標代碼
java,C#
解釋:高級語言–> 解釋器–> 機器代碼
shell, perl, python
編程邏輯處理方式:
順序執行
循環執行
選擇執行
shell 編程:過程式、解釋執行
編程語言的基本結構:
數據存儲:變量、數組
表達式: a + b
語句:if
shell 腳本是包含一些命令或聲明,并符合一定格式的文
本文件
格式要求:首行shebang 機制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
shell 腳本的用途有:
自動化常用命令
執行系統管理和故障排除
創建簡單的應用程序
處理文本或文件
創建shell腳本
第一步:使用文本編輯器來創建文本文件
第一行必須包括shell 聲明序列:#!(要頂格寫)
#!/bin/bash
添加注釋
注釋以# 開頭
第二步:運行腳本
給予執行權限,在命令行上指定腳本的絕對或相對路徑
直接運行解釋器,將腳本作為解釋器程序的參數運行
可以是用:bash 腳本名稱
這種用法是再打開一個子shell,在子shell中運行,不對當前環境改變
source 腳本名稱
. 腳本名稱
source 和.一樣,會對當前的環境改變
腳本的調試:
bash -n /path/to/some_script
檢測腳本中的語法錯誤
bash -x /path/to/some_script
調試執行
變量:
變量:命名的內存空間
數據存儲方式:
字符:
數值:整型,浮點型
變量類型
作用:
1 、數據存儲格式
2 、參與的運算
3 、表示的數據范圍
類型:
字符
數值:整型、浮點型
編程程序語言分類:
強類型:定義變量時必須指定類型、參與運算必須符合類型要求;調用未聲明變量會產生錯誤
如 java,python
弱類型:無須指定類型,默認均為字符型;參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
如 :bash 不支持浮點數
變量命名法則:
1 、不能使程序中的保留字:例如if, for;
2 、只能使用數字、字母及下劃線,且不能以數字開頭
3 、見名知義
4 、統一命名Shell腳本包括一些命令或聲明,并符合一個格式的文件
Bash中變量的種類
根據變量的生效范圍等標準:
本地變量:生效范圍為當前shell 進程;對當前shell 之外的其它shell 進程,包括當前shell 的子shell 進程均無效
環境變量:生效范圍為當前shell 進程及其子進程
局部變量:生效范圍為當前shell 進程中某代碼片斷( 通常指函數)
位置變量:$1, $2, … 來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
特殊變量:$?, $0, $*, $@, $#
本地變量:
變量賦值:name=‘value’, ,
可以使用引用value:
(1) 可以是直接字串; name=“root"
(2) 變量引用:name="$USER"
(3) 命令引用:name=` COMMAND `, name =$(COMMAND)
變量引用:${name}, $name
"" :弱引用,其中的變量引用會被替換為變量值
'' :強引用,其中的變量引用不會被替換為變量值,而保
持原字符串
顯示已定義的所有變量:set
刪除變量:unset name
舉例演示:
1編寫腳本/root/bin/systeminfo.sh.顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
腳本:
2、編寫腳本/root/bin/backup.sh ,可實現每日將/etc/ 目錄備份到/root/etcYYYY-mm-dd中
腳本:
3、編寫腳本/root/bin/disk.sh, 顯示當前硬盤分區中空間利用率最大的值
4、編寫腳本/root/bin/links.sh, 顯示正連接本主機的每個遠程主機的IPv4 地址和連接數,并按連接數從大到小排序
腳本:
環境變量:
變量聲明、賦值:
export name=VALUE
declare -x name=VALUE
變量引用:$name, ${name}
顯示所有環境變量命令:
export
env
printenv
刪除:unset name
bash 有許多內建的環境變量:PATH, SHELL, USRE,UID,
HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1
只讀變量:
只讀變量:只能聲明,但不能修改和刪除
readonly name
declare -r name
位置變量
位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
$1, $2, … :對應第1 、第2 等參數,shift [n] 換位置
$0: 命令本身
$*: 傳遞給腳本的所有參數,全部參數合為一個字符串
$@: 傳遞給腳本的所有參數,每個參數為獨立字符串
$#: 傳遞給腳本的參數的個數
$@ $* 只在被雙引號包起來的時候才會有差異(兩者差異之處是,$*會把所有的參數當成一個整體;
而$@會把所有參數分別對待;)
示例:判斷給出的文件的行數
linecount="$(wc -l $1| cut -d' ' -f1)"
echo "$1 has $linecount lines."
算術運算
bash 中的算術運算:help let
+, -, *, /, % 取模(取余), ** (乘方)
實現算術運算:
(1) let var= 算術表達式
(2) var=$[ 算術表達式]
(3) var=$(( 算術表達式))
(4) var=$(expr arg1 arg2 arg3 …)
(5) declare –i var = 數值
(6) echo ‘ 算術表達式’ | bc
(7) seq -s + 數值 數值 :計算兩個數值之間的所有數的和
(8) scale 命令可以幾位保留精度
scale=2 表示保留兩位精度(只對除法、取余、乘冪有效)
例如:保留兩位精度,echo "scale=2;111/22;" |bc 或者
bc <<< "scale=2;111/22;"
乘法符號有些場景中需要轉義 ,如 如*
bash 有內建的隨機數生成器:$RANDOM (1-32767) )
echo $[$RANDOM%50] :0-49
賦值
增強型賦值:
+=, -=, *=, /=, %=
let var OPER value
例如:let count+=3
自加3 后自賦值
自增,自減:
let var+=1 每次自加1
let var++ 每次自加1
let var-=1 每次自減1
let var— 每次自減1
舉例演示:
1 :寫一個腳本/root/bin/sumid.sh ,計算/etc/passwd文件中的第10 個用戶和第20 用戶的ID 之和
腳本:
2 :寫一個腳本/root/bin/sumspace.sh ,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
腳本:
3 :寫一個腳本/root/bin/sumfile.sh, 統計/etc, /var, /usr目錄共有多少個一極子目錄和文件
腳本:
邏輯運算
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
退出狀態
進程使用退出狀態來報告成功或失敗
0 代表成功,1 -255 代表失敗
$? 變量保存最近的命令退出狀態
例如:
$ ping -c1 -W1 hostdown &> /dev/null
$ echo $?
退出狀態碼
bash 自定義退出狀態碼
exit [n] :自定義退出狀態碼;
注意:腳本中一旦遇到exit 命令,腳本會立即終止;終止退出
狀態取決于exit 命令后面的數字
注意:如果未給腳本指定退出狀態碼,整個腳本的退出狀態碼
取決于腳本中執行的最后一條命令的狀態碼
條件測試
判斷某需求是否滿足,需要由測試機制來實現;
專用的測試表達式需要由測試命令輔助完成測試過程;
評估布爾聲明,以便用在條件性執行中
若真,則返回0
若假,則返回1
測試命令:
test EXPRESSIO
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION前后必須有空白字符
條件性的執行操作符
根據退出狀態而定,命令可以有條件地運行
&& 代表條件性的AND THEN
|| 代表條件性的OR ELSE
Bash的測試類型
數值測試:
-gt: 是否大于;
-ge: 是否大于等于;
-eq: 是否等于;
-ne: 是否不等于;
-lt: 是否小于;
-le: 是否小于等于
字符串測試:
== :是否等于;
>: ascii 碼是否大于ascii碼 碼
<: 是否小于
!=: 是否不等于
=~: 左側字符串是否能夠被右側的PATTERN所 所 匹配
注意: 此表達式一般用于[[ ]] 中;
-z "STRING" :字符串是否為空,空為真,不空為假
-n "STRING" :字符串是否不空,不空為真,空為假 (要用雙中括號‘[[]]’)
注意:用于字符串比較時的用到的操作數都應該使用引號
舉例演示:
1 、寫一個腳本/root/bin/argsum.sh ,接受一個文件路徑作為參數;如果參數個數小于1 ,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1 ,則顯示第一參數所指向的文件中的空白行數
腳本:
2 、寫一個腳本/root/bin/hostping.sh ,接受一個主機的IPv4 地址做為參數,測試是否可連通。如果能ping 通,則提示用戶“該IP 地址可訪問” ;如果不可ping 通,則提示用戶“該IP 地址不可訪問”
腳本:
文件測試
存在性測試
-a FILE :同-e
-e FILE: 文件存在性測試,存在為真,否則為假;
存在性及類別測試
-b FILE :是否存在且為塊設備文件;
-c FILE :是否存在且為字符設備文件;
-d FILE :是否存在且為目錄文件;
-f FILE :是否存在且為普通文件;
-h FILE 或 或 -L FILE :存在且為符號鏈接文件;
-p FILE :是否存在且為命名管道文件;
-S FILE :是否存在且為套接字文件
文件權限測試:
-r FILE :是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行
文件特殊權限測試:
-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;
組合測試條件
第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非 非
如:[ -e FILE ] && [ -r FILE ]
第二種方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必須使用測試命令進行
舉例演示:
1 、chmod -rw /tmp/file1 ,編寫腳本/root/bin/per.sh,判斷當前用戶對/tmp/fiile1文件 是否不可讀且不可寫
腳本:
2 、編寫腳本/root/bin/nologin.sh 和login.sh, 實現禁止和允許普通用戶登錄系統
腳本:
禁止登錄:
允許登錄:
使用read 來把輸入值分配給一個或多個shell 變量:
-p 指定要顯示的提示
-t TIMEOUT
read 從標準輸入中讀取值,給每個單詞分配一個變量
所有剩余單詞都被分配給最后一個變量
read -p “Enter a filename: “ FILE
流程控制
過程式編程語言:
順序執行
選擇執行
循環執行
條件選擇if語句
選擇執行:
注意: :if 語句可 嵌套
單分支
if 判斷條件:then
條件為真的分支代碼
fi
雙分支
if 判斷條件; then
條件為真的分支代碼
else
條件為假的分支代碼
fi
多分支
if CONDITION1 ; then
if-true
elif CONDITION2 ; then
if-ture
elif CONDITION3 ; then
if-ture
…
else
all-false
fi
逐條 件進行判斷,第一次遇為“真”條件時,執行其分支,而后 結束整個if 語句
條件判斷:case語句
case 變量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
…
*)
默認分支
;;
esac
case 支持glob 風格的通配符:
*: 任意長度任意字符
?: 任意單個字符
[] :指定范圍內的任意單個字符
a|b: a或b
舉例演示:
1 、寫一個腳本/root/bin/createuser.sh ,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之;顯示添加的用戶的id 號等信息
腳本:
2 、寫一個腳本/root/bin/yesorno.sh ,提示用戶輸入yes或 或no, 并判斷用戶輸入的是yes 還是no, 或是其它信息
腳本:
3 、寫一個腳本/root/bin/filetype.sh, 判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,鏈接,其它文件類型)
腳本:
4 、寫一個腳本/root/bin/checkint.sh, 判斷用戶輸入的參數是否為正整數
腳本:
5、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤
滿
腳本:
6、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限
7、判斷輸入的IP是否為合法IP
腳本:
8、計算1+2+3+…+100
腳本:
9、輸入起始值A和最后值B,計算從A+(A+1)…+(B-1)+B的總和
腳本:
原創文章,作者:ZJM,如若轉載,請注明出處:http://www.www58058.com/35902