Linux基礎教程之shell腳本使用入門
1、編程基礎
- ? 程序:指令+數據
- ? 程序編程風格:
? ? ? ? ? ? ? ? ? ? ? ? 過程式:以指令為中心,數據服務于指令
? ? ? ? ? ? ? ? ? ? ? ? 對象式:以數據為中心,指令服務于數據
- ? shell程序:提供了編程能力,解釋執行
2、程序的執行方式
- ? ? ? ? 計算機:運行二進制指令
- ? ? ? ? 編程語言:
? ? ? ? ? ? ? ? ? ? 低級:匯編
? ? ? ? ? ? ? ? ? ? 高級:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?編譯:高級語言– >編譯器–> 目標代碼
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?C,C++,C#,Go
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?解釋:高級語言–> 解釋器–> 機器代碼
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shell,perl , Python , JAVA
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? JavaScript , ruby ,PHP
3、編程基本概念
- ? ? ?? 編程邏輯處理方式:
? ? ? ? ? ? ? ? ?順序執行
? ? ? ? ? ? ? ? ?循環執行
- ? ? ?? shell編程 :過程式、解釋執行
? ? ? ? ? ? ? ? ?編程語言的基本結構:
? ? ? ? ? ? ? ? ? ?各種系統命令的組合
? ? ? ? ? ? ? ? ? ?數據存儲:變量、數組
? ? ? ? ? ? ? ? ? ? ? ? ?表達式:a+b
? ? ? ? ? ? ? ? ? ?語句:if
4、shell腳本基礎
- ? ? ? shell腳本:
? ? ? ? ? ? ? ? 包含一些命令或聲明,并符合一定格式的文本文件
- ? ? ? 格式要求:首行shebang機制
? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? # ! /usr/bin/Python
? ? ? ? ? ? ? ? #!/usr/bin/perl
- ? ? ? shell腳本的用途有:
? ? ? ? ? ? ? ? > ? 自動化常用命令
? ? ? ? ? ? ? ? > ? 執行系統管理和故障排除
? ? ? ? ? ? ? ? > ? 創建簡單的應用程序
? ? ? ? ? ? ? ? > ? 處理文本或文件
5、創建shell腳本
- ? ? ? 第一步:使用文本編輯器來創建文本文件
? ? ? ? ? ? ? ? > ?第一行必須包括shell聲明序列:#!
? ? ? ? ? ? ? ? #!/bin/bash
? ? ? ? ? ? ? ? > 添加注釋
? ? ? ? ? ? ? ? ? ? 注釋以#開頭
- ? ? ? 第二步:運行腳本
? ? ? ? ? ? ? ? > 給予執行權限,在命令行上指定腳本的絕對或相對路徑
? ? ? ? ? ? ? ? > 直接運行解釋器,將腳本作為解釋器程序的參數運行
6、shell腳本示例
? ? ? #!/bin/bash
? ? ? #Author?:Li
? ? ? #Version : 1.0
? ? ? #Date : 2017-04-01
? ? ? #Description :The script displays system information
? ? ? ?echo”Greetings.The date and time are $(date)”
? ? ? ?echo “Your working directory is : $(pwd)”
7、腳本調試
- 檢測腳本中的語法錯誤
? ? ? ? ?bash -n /path/to/some_script
- 調試執行
? ? ? ? ?bash -x /path/to/some_script
8、變量
- 變量:暫時存放數據的地方,一個具有名稱的內存地址空間。
? ? ? ? ? 數據存儲方式:
? ? ? ? ? ? ? ? ? ? ? ? ? 字符:
? ? ? ? ? ? ? ? ? ? ? ? ? 數值:整形,浮點型
- 變量:變量類型
? ? ? ? ? 作用:
? ? ? ? ? ? ? ? ? 1、數據存儲格式
? ? ? ? ? ? ? ? ? 2、參與的運算
? ? ? ? ? ? ? ? ? 3、表示的數據范圍
? ? ? ? ? 類型:
? ? ? ? ? ? ? ? ? ?字符
? ? ? ? ? ? ? ? ? ?數值:整形、浮點型
- 強類型:變量不經過強制轉換,它永遠是這個數據類型,不允許隱式的類型轉換。一般定義變量時必須指定類型參與運算必須符合類型要求;調用未聲明變量會產生錯誤
? ? ? ? ? ? ? ? ? ?如 ?java,c#
- 弱類型:語言的運行時會隱式做數據類型轉換。無須指定類型,默認均為字符型;
? ? ? ? ? 參與運算會自動進行隱式類型轉換;變量無須事先定義可直接調用
? ? ? ? ? 如:bash不支持浮點數,php
- 變量命名法則:
? ? ? ? ? 1、不能使程序中的保留字:例如if,for
? ? ? ? ? 2、只能使用數字、字母及下劃線,且不能以數字開頭
? ? ? ? ? 3、見名知義
? ? ? ? ? 4、統一命名規則:駝峰命名法
- 變量的命名規范
? ? ? ? ? >使用英文字母,數字及下劃線組成;
? ? ? ? ? >開頭第一個字母不能使用數字
? ? ? ? ? >Beijing
? ? ? ? ? >BEIJING
? ? ? ? ? >BeiJing
? ? ? ? ? >Bei_Jing
? ? ? ? ? >_Bei_Jing
9、bash中變量的種類
- 根據變量的生效范圍等標準:
?????????? 本地變量(全局變量):生效范圍為當前shell進程;對當前shell之外的其它shell進程,包括當
?????????? 前shell之外的其它shell進程,包括當前shell的子shell進程均無效
?????????? 環境變量:生效范圍為當前shell進程及其子進程
?????????? 局部變量(私有變量):生效范圍為當前shell進程中某代碼片段(通常指函數)
?????????? 位置變量:$1,$2,…來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它的參數
?????????? 特殊變量:$?,$0,$*,$@,$#,$$
10、本地變量
- 變量賦值:name=’value’
- 可以使用引用value:
????????? (1)可以是直接字串;name=“root”
????????? (2)變量引用:name=”$USER”
????????? (3)命令引用:name=`COMMAND`? name=$(COMMAND)
- 變量引用:${name}? $name
????????? “”:弱引用,其中的變量引用會被替換為變量值
????????? ” :強引用,其中的變量引用不會被替換為變量值,而保持原字符串
- 顯示已定義的所有變量:set
- 刪除變量:unset name
11、環境變量
- 變量聲明、賦值:
??????? export name=VALUE
??????? declare -x name=VALUE
- 顯示所有環境變量:
?????????? env,printenv,export,declare -x,set
- 刪除:unset name
- bash有許多內建的環境變量:PATH ,SHELL ,USRE,UID,
????????? HISTSIZE,HOME,PWD,OLDPWD,HISTFILE
12、環境變量
- $PATH 命令的搜尋路徑
- $OLDPWD 前一個工作目錄
- $LANG 目前的工作語系
- $BASH bash的完整路徑名
- $BASH_VERSION Bash的版本
- $HISTCONTROL 控制指令是否存入歷史文件中
- $OSTYPE 顯示系統類型
- $MAIL 存放郵件的文件
- $MAILCHECK 多久檢查一下郵件
- $PWD 當前路徑
- $SSH_TTY 當前登錄的TTY
- $SHLVL 當前shell在第幾層
- $RANDOM 隨機數
13、只讀和位置變量
- 只讀變量:只能聲明,但不能修改和刪除
????????? >聲明只讀變量:
????????? readonly name
????????? declare -r name
????????? >查看只讀變量:
????????? readonly -p
- 位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
?????????? $1,$2, ….: 對應第1、第2等參數,shift [n]換位置
?????????? $0:命令本身
?????????? $*:傳遞給腳本的所用參數,全部參數合為一個字符串
?????????? $@:傳遞給腳本的所有參數,每個參數為獨立字符串
?????????? $#:傳遞給腳本的參數的個數
???????????????? $@ $* 只在被雙引號包起來的時候才會有差異
?????????? set — 清空所有位置變量
14、算術運算
- bash中的算術運算:help let
????????? +,-,*,/,%取模(取余),**(乘方)
????????? 實現算術運算:
????????? (1)let num=算術表達式 let r=9+9
????????? (2)var=$[算術表達式]???? r=$[9+9]
????????? (3)var=$((算術表達式))?? r=$((9+9))
????????? (4)外部命令?? expr??? expr? 8+3
????????? (5)declare -i? var = 數值 declare -i r=9+9
????????? (6)echo ‘算術表達式’ | bc??? echo? “8+8”? | bc
- 乘法符號有些場景中需要轉義,如*
- bash有內建的隨機數生成器:$RANDOM(0-32767)
?????????? echo $[$RANDOM%50]:0-49之間隨機數
- 思考:
- unset i
- echo $((12+$i))是否可以執行
15、賦值
- 增強型賦值:
??????????? +=,-=,*=,/=,%=
- let varOPERvalue
?????????? 例如:let count+=3
???????????????????? 自加3后自賦值
- 自增,自減:
?????????? let var+=1
?????????? let var++
?????????? let var-=1
?????????? let var–
16、邏輯運算
- 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,第二個必須要參與運算
17、退出狀態
- 進程使用退出狀態來報告成功或失敗
???????? > 0 代表成功,1-255代表失敗
???????? > $? 變量保存最近的命令退出狀態
- 例如:
????????? $ ping? -c1? -W1? hostdown? &>? /dev/null
????????? $ echo $?
18、退出狀態碼
- bash自定義退出狀態碼
???????? exit [n]:自定義退出狀態碼
???????? 注意:退出中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命令后面的數字
???????? 注意:如果未給腳本指定狀態碼,整個腳本的退出狀態碼取決于腳本中執行的最后一條命令的
?????????????????? 狀態碼
19、條件測試
- 判斷某需求是否滿足,需要由測試機制來實現
???? 專用的測試表達式徐奧由測試命令輔助完成測試過程
- 評估布爾聲明,以便用在條件性執行中
???????? > 若真,則返回0
????? .? > 若假,則返回1
- 測試命令:
???????? >? test EXPRESSION
???????? >? [ EXPRESSION ]
???????? >? [ [ EXPRESSION ] ]
????????????? 注意:EXPRESSION前后必須有空白字符
20、條件性的執行操作符
- 根據退出狀態而定,命令可有條件地運行
?????????? >? && 代表條件性的AND THEN
?????????? >? ||?? 代表條件性的OR ELSE
- 例如:
?????? $ grep -q no_such_uesr? /etc/passwd?
?????? | | echo ‘No such user’
?????? No such user
?????? $ ping? -c1? -W2? station1? &>? /dev/null?
????????? > &&? echo? “station1? is? up”????
????????? >? ||? (echo ‘station1 is unreachable’ : exit1)
????????? station1? is? up
21、test命令
- 長格式的例子:
?????????? $ test “$A”? ==? “$B”? &&? echo? “Strings? are? equal”
?????????? $ test “$A”? -eq? “$B”??
???????????? &&? echo? “Integers are equal”
- 簡寫格式的例子:
????????? $? [? “$A”? ==? “$B”? ]? &&? echo? “Strings are equal”
????????? $? [? “$A” -eq? “$B”? ]? &&? echo? “Integers are equal”
22、bash的測試類型
??????? -gt:是否大于
??????? -ge:是否大于等于
??????? -eq:是否等于
??????? -ne:是否不等于
??????? -lt:是否小于
??????? -le:是否小于等于
23、bash的測試類型
- 字符串測試
???????????????????? ==:是否等于;
????????????????????? >? : ascii碼是否大于ascii碼
????????????????????? <? :? 是否小于
??????????????????? !=:是否不等于
??????????????????? =~:左側字符串是否能夠被右側的PATTERN所匹配
??????????????????????????? 注意:此表達式一般用于[[? ]]中;擴展的正則表達式
??????????????????????? -z? “STRING”: 字符串是否為空,空為真,不空為假
??????????????????????? -n? “STRING”: 字符串是否不空,不空為真,空為假
- 注意:用于字符串比較時的用到的操作數都應該是使用引號
24、文件測試
- 存在性測試
????????? -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 :是否存在且可執行
- 文件特殊權限測試:
????????? -u FILE : 是否存在且擁有suid權限
????????? -g FILE: 是否存在且擁有sgid權限
????????? -k FILE:是否存在且擁有sticky權限
25、組合測試條件
- 第一種方式:
????????? COMMAND1 && COMMAND2 并且
????????? COMMAND1 | |? COMMAND2 或者
???????? !COMMAND 非
?????????? 如:[[ -r FILE ]] && [[ -w FILE ]]
- 第二種方式:
???????? EXPRESSION1 -a EXPRESSION2 并且
???????? EXPRWSSION1 -o EXPRESSION2? 或者
??????? !EXPRESSION
????????? “!”最高, “-a”次之,”-o”最低。
??????? 示例:
??????????????? # [ -z? “$HOSTNAME” -o $HOSTNAME “== “localhost.localdmain” ] && hostname
???????????????????haohuigou.com
??????????????? # [ -f? /bin/cat -a -x /bin/cat ] && cat /etc/fstab
26、使用read命令來接受輸入
- 使用read來把輸入值分配給一個或多個shell變量:
??????????? -p? 指定要顯示的提示
??????????? -s? 靜默輸入
??????????? -n? N指定輸入的字符長度N
???????????? -d? ‘字符‘? 輸入結束符
???????????? -t? N? TIMEOUT為N秒
???????????? read? 從標準輸入中讀取值, 給每個單詞分配一個變量所有剩余單詞都被分配給最后一個變
????????????????????? 量
???????????? read -p “Enter a filename:”? FILE
27、bash如何展開命令行
- 把命令行分成單個命令詞
- 展開別名
- 展開大括號的聲明({})
- 展開波浪符聲明(·)
- 命令替換$( )?? 和? “)
- 再次把命令行分成命令詞
- 展開文件通配(*、?、[abc]等等)
- 準備I/O重導向 (<、>)
- 運行命令
28、防止擴展
- 反斜線()會使隨后的字符按愿意解釋
?????????? $? echo? Your? cost:? $5.00
?????????? Your? cost? :? $5.00
- 加引號來防止擴展
?????????? >單引號(’)防止所有擴展
?????????? >雙引號(”)也防止所有擴展,但是一下情況例外:
????????????? >$(美元符號)??? —? 變量擴展
????????????? >`? (反引號)??????? —? 命令替換
????????????? > (反斜線)?? —?? 禁止單個字符擴展
????????????? > !(? 嘆號? )??? —? 歷史命令替換
29、bash的配置文件
- 按生效范圍劃分,存在兩類:
- 全局配置:
?????????? /etc/profile
?????????? /etc/profile.d/*.sh
?????????? /etc/bashrc
- ~/.bash_profile
- ~/.bashrc
30、shell登錄兩種方式
- 交互式登錄:
????? (1) 直接通過終端輸入賬號密碼登錄;
????? (2)使用”su – UserName” 切換的用戶
???????? 執行順序:
???? /etc/profile — > /etc/profile.d/*.sh — >
~/.bash_profile — > ~/ .bashrc — > /etc/bashrc
- 非交互式登錄:
?????? (1)su UserName
?????? (2)圖形界面下打開的終端
?????? (3)執行腳本
????? 執行順序:
????????????? ~/ .bashrc –> /etc/bashrc –> /etc/profile.d/*.sh
31、Profile類
- 按功能劃分,存在兩類:
?????????? profile類和bashrc類
- profile類:為交互式登錄的shell提供配置
?????????? 全局: /etc/profile, /etc/profile.d/*.sh
?????????? 個人 : ~/.bash_profile
?????????? 功用:
?????????? (1)用于定義環境變量
?????????? (2)運行命令或腳本
32、Bashrc類
- bashrc類 :為非交互式和交互式登錄的shell提供配置
?????????? 全局:/etc/bashrc
?????????? 個人:~/ .bashrc
?????????? 功用:
?????????? (1) 定義命令別名和函數
?????????? (2) 定義本地變量
33、編輯配置文件生效
- 修改profile和bashrc文件后需生效
??????????? 兩種方法:
????????? 1 重新啟動shell進程
????????? 2 . 或source
?????????? 例:
???????????????? .~/.bashrc
34、Bash 退出任務
- 保存在~/.bash_logout文件中(用戶)
- 在退出登錄shell時運行
- 用于
????????????? > 創建自動備份
????????????? > 清除臨時文件
35、變量高級操作
- 測試變量存在性
- 字符串切片
?????????? 1 ${變量:位置起點}
???????????????????????????? 由指定的位置開始,截取字符串到字符串結束
??????????????? eg:MYNAME=”liangchenye”
???????????????????? substr=${MYNAME:4}
?????????? 2 ${變量: 位置起點: 長度}
???????????? eg:MYNAME=”liangchenye”
???????????????????? substr2=${MYNAME:4:6}
- 計算字符串長度
?????????? >${#變量名稱}
?????????? >傳回變量值的字符串長度
?????????????????????????? filename=”/usr/sbin/ntpd”
?????????????????????????? echo ${#filename}
???????????? PS:另外一種方法:
???????????? expr? length??? “$filename”
- 由前面(最左邊)開始,對比變量值,刪除“最短相符合的字符串”
?????????? > ${變量#樣式}
?????????? > filename=”/usr/sbin/ntpdate”
?????????????? echo ${filename#/*/}
????????? 由前面對比,刪除最長的
????????????? ${變量##樣式}
????????? > filename=”/usr/sbin/ntpdate”
?????????????? echo ${filename##/*/}
- 由后面對比,刪最短的
?????????? >${變量%樣式}
?????????? >filename=” /usr/sbin/ntpd”
?????????? > echo ${filename%/*}
?????????? 由后面對比,刪最長的
?????????? ${變量%%樣式}
??????????? domainname=”www.178Linux.com”
???????????? echo ${domainname%%.*}
- 只替換第一個對比符合的字符串
?????????? > ${變量/樣式/字符串}
?????????? >? name=”liangchenye”
?????????? > echo ${name/liang/wang}
- 替換全部對比符合的字符串
?????????? > ${變量//樣式/替換字符串}
?????????? > name=”zhaoritianzhaoritian”
?????????? > echo? ${name//zhao/ye}
- 把對比符合的字符串刪除
????????? > 只刪除一個 ec
????????? > ${變量/樣式/}
????????? > name=“liangchenye”
????????? > echo ${name//zhao/}
36、變量操作:測試存在值及空值
- ${待測變量-默認值}
?????????? >若變量不存在,則符合判斷,傳回默認值
?????????? > unset myname
?????????? >? echo? ${myname-“fuerkang”}
- ${待測變量:=默認值}
?????????? >若變量號不存在或其值為空,則符合判斷,傳回默認值
?????????? > unset myneme
?????????? > echo? ${myname := “fuerkang”}
37、循環判斷 if
- 判斷之if
???????? >結構
???????? >書寫格式
38、循環判斷 for
- 循環之for
??????? >書寫格式
??????? > c類型
- 循環中斷
??????? > continue
??????? > break
39、循環判斷? while? until
- 循環之while
????????? >書寫格式
- 循環之until
????????? >書寫格式
- while和until區別
????????? >while為真執行后面代碼段
????????? >until?? 為真是停止執行
- 循環中斷
????????? >continue
????????? >break
- while,until和for的區別
??????????? >for? 可預見
??????????? > while,until不可預見
循環判斷? case
- 判斷之case
????????? >書寫格式
????????? >常用使用場景
40、函數
- 函數
??????????? >定義
??????????? >調用
??????????? >作用:實現代碼重用
??????????? >位置函數作為參數
41、數組
- 聲明
?????????? >a=(1 2 3 4)
?????????? >a[0]=1? a[1]=2
?????????? >a=([0]=1 [1]=2 [3]=4)
- 顯示數組所有元素
?????????? .>echo? ${a[*]}
??????????? >echo? ${a[@]}
- 顯示數組所有索引
??????????? >echo? ${!a[@]}
- 使用索引顯示元素
??????????? >echo ${a[0]}
- 數組元素個數
??????????? >echo ${#a[@]} 或 echo ${#a[*]}