-
SHELL腳本
-
-
編程語言的分類-
解釋型語言:shell,Python,需要解析器
-
編譯型語言:C語言,C++,需要編譯器
-
-
shell腳本
-
操作系統的結構
-
shell(貝殼)
-
應用層
-
app,代碼
-
應用層需要通過shell完成和內核的交互
-
-
-
內核層
-
設備管理
-
文件管理
-
網絡管理
-
進程管理
-
內存管理
-
-
硬件層
-
外部設備
-
-
-
-
第一個shell腳本
-
shell腳本的本質: 指令的集合
-
C語言文件 .c
-
shell文件 .sh
-
C++文件 .cpp
-
-
-
#!/bin/bash
-
#!用于指明該腳本默認使用shell解析器
-
說明使用的是shell解析器
-
-
echo hello
-
輸出hello
-
echo 打印指令將hello輸出
-
-
-
#
-
在shell中表示注釋
-
-
-
執行腳本的三種方式
-
bash 文件名
-
通過解析器,直接解析腳本
-
bash 1.sh
-
執行過程:在后臺打開一個終端
-
-
-
直接運行腳本
-
需要給腳本添加可執行權限
-
chmod 777 1.sh
-
直接在終端輸入1.sh
-
-
-
source 腳本名
-
前臺打開一個終端,執行腳本和返回腳本都在當前終端
-
-
-
-
修改環境變量
-
查看已有的特殊系統變量
-
env
-
-
查看環境變量
-
echo $PATH
-
環境變量的作用:當在終端直接運行指令時,去默認環境變量保存的路徑中查找指令,如果沒找到該指令不能執行
-
-
修改環境變量
-
只對當前終端有效
-
export PATH = ${PATH}:/home/ubunutu
-
export : 給系統變量賦值
-
PATH:被賦值的變量
-
=:賦值
-
${PATH} : 拿到之前PATH的值
-
::分隔
-
/home/ubuntu:添加的路徑
-
-
代碼運行的作用:在當前終端給PATH添加了一個/home/ubuntu路徑
-
-
只對當前用戶有效
-
修改家目錄下的~/.bashrc文件
-
由于是當前用戶下的家目錄,所以不需要加sudo
-
-
vim ~/.bashrc
-
然后將export表達式添加到文件的尾部
-
-
修改文件后需要運行文件才能生效
-
source ~/.bashrc
-
重啟虛擬機
-
-
-
對所有用戶生效
-
修改/etc/enviroment
-
sudo vim /etc/enviroment
-
只有一行PATH的信息,想要添加的路徑
-
-
-
修改/etc/bash.bashrc文件
-
sudo vim /etc/bash.bashrc
-
使用export表達式,添加路徑
-
-
-
-
-
-
shell中的變量
-
shell中的變量沒有數據類型的區別,shell是一種弱數據類型語言,都當字符串處理
-
格式:
-
變量名 = ‘變量的值’
-
用于變量值內有空格時,無$獲取變量的值
-
-
變量名 = “變量的值”
-
可以$變量的展開
-
-
變量名 = 變量的值
-
= 號兩側不能有空格
-
-
-
獲取變量
-
$變量名
-
${變量名}
-
為了更好的區分變量名的范圍
-
-
-
修飾變量的關鍵字
-
readonly
-
只讀變量,值不能更改
-
-
unset
-
清空變量的值,不能清空readonly修飾的值
-
-
local
-
定義局部變量(只能在函數中使用)
-
-
-
外部傳參/位置變量
-
和C語言相同,腳本也可以在執行時進行外部傳參,shell中通過位置變量獲取參數
-
$0
-
獲取腳本名
-
-
$n
-
獲取第n個外部參數
-
n>10時需在n外加上大括號,否則只能讀取一位
-
-
-
$#
-
獲取所有外部參數的個數
-
-
$*/$@
-
獲取所有的外部參數
-
-
-
輸出
-
echo
-
echo 輸出內容(將內容回顯到終端,并自動換行)
-
echo默認不解析轉義字符
-
echo -n 輸出內容
-
取消echo輸出時的換行
-
-
echo -e "hello\n"
-
解析轉義字符
-
-
-
-
指令的格式:指令 參數 操作數
-
有些指令也支持:指令 操作數 參數
-
echo 不支持
-
-
指令的標準格式
-
-
輸入
-
復習:C中使用scanf、gets、getchar需要變量的地址
-
shell中使用read指令完成輸出
-
read
-
read 變量名
-
直接加變量名即可,可以讀入帶空格的數據
-
-
read -p "提示信息" 變量名
-
在終端給用戶輸出提示信息
-
-
read -s 變量名
-
輸入的信息不回顯
-
-
read -t 秒數 變量名
-
如果n秒用戶不輸入,就結束輸入向后執行語句
-
-
read -n 個數 變量名
-
如果輸入n個字符,自動停止
-
-
-
-
命令置換符
-
作用:獲取指令的執行結果
-
`命令` (反引號)
-
$(命令)
-
-
-
shell中的數組
-
shell中支持稀疏數組
-
定義
-
數組名=(初始值1 初始值2 初始值3 ····)
-
#shell中的數組,不需要寫出數組長度
-
#shell中數組初始化時,直接使用()
-
#shell中的數組每個元素之間是空格不是逗號
-
#訪問仍然通過下標訪問,并且下標仍然從0開始
-
數組名=([下標]=初始值 [下標]=初始值 ····)
-
下標可以不連續
-
-
-
訪問數組中的元素
-
${數組名[下標]}
-
獲取數組中指定下標的元素的值
-
-
要在shell中需要使用變量的值,都要用$進行訪問
-
-
獲取數組中元素的個數
-
${#數組名[*/@]}
-
獲取數組中已經賦值的元素的個數
-
-
${#數組名[下標]}
-
獲取數組中指定下標元素的長度(字符個數)
-
-
-
稀疏數組
-
下標不連續的數組
-
稀疏數組中元素的個數,由不為空的數據的個數決定
-
數組名=([下標]=初始值 [下標]=初始值 ····)
-
下標可以不連續 初始值可以是任意字符/串
-
-
-
使用已有的數組給新的數組賦值
-
arr=(1 2 3 4 5) arr1=(a b c d) #定義一個arr2數組使用已有的arr和arr1數組賦值 arr2=(${arr1[*]} ${arr[*]}) #拼接加空格 echo ${arr2[*]} echo ${#arr2[*]}
-
拼接時兩個數組中間沒有加空格, 第一個數組中的對后一個元素和第二個數組中的第一個元素會被拼接到一起
-
拼接時兩個數組中間加空格,兩個數組獨立起來拼接
-
-
-
-
shell中的運算
-
shell本身不擅長運算,需要借助運算符和其他指令
-
(())
-
常用于shell中的整數算術運算
-
(())幾乎支持所有的C語言語法
-
((表達式1,表達式2,表達式3,·······)) 每一個表達式都會執行,獲取最右側一個表達式的結果
-
想要獲取運算的結果,需要使用$(()),還可以((變量名=表達式))
-
在(())中,使用變量的值,可以加$也可以不加$ (建議在(())直接使用變量的值,不加$)
-
在(())中,運算符兩側可以有空格
-
-
$[]
-
變量名=$[表達式1,表達式2,表達式3,·······]只獲取最右側表達式的結果
-
使用變量時,可以加$也可以不加$
-
運算符兩側可以加空格,也可以不加空格
-
$[]的結果,建議直接按照"變量名=$[]"格式接收,因為$[]本質上,會遺留一個運算結果在表達式的位置,如果不接受繼續向后運行指令會報錯
-
-
let
-
let 變量名=表達式
-
let和變量名中間一定要有空格
-
-
let中使用變量,可以加$也可以不加$
-
let運算時,運算符兩側一定不能有空格
-
如果直接寫成 let 表達式,表達式會運行,但是沒有返回值
-
-
expr
-
格式:expr 表達式
-
是一個終端指令
-
故而expr中使用變量,必須加$
-
-
如果想要接收expr的結果,必須使用命令置換符
-
expr中運算符兩側必須有空格,不支持自增、自減和shell中的冪運算
-
expr中使用某些運算符時,需要轉義|、>、<、.、······ (不需要記轉義字符,簡單的指令在運行前,去終端里運行一下指令,沒結果就加上轉義字符)
-
expr指令的結果,可以直接回顯到終端上,故使用命令置換符接收回顯值
-
expr操作數的值不能為空
-
如果expr的操作數為空會報語法錯誤
-
-
expr進行整數算術運算
-
expr(字符串運算)
-
match 字符串 表達式
-
返回表達式,在字符串中第一個位置起完全匹配成功的字符個數,如果能夠匹配成功,返回值就是表達式中字符的個數
-
expr match "$str1" $str2
-
由于str1中有空格,需用雙引號引起來
-
-
str2不能在str1中的第一個位置開始完全匹配返回0
-
-
substr 字符串 偏移量 長度
-
從字符串中偏移量的位置開始 截取指定長度的字串,偏移量從1開始
-
expr substr "$str1" 7 5
-
截取出字符串的子串world
-
substr : 字符串的子串
-
-
-
index 字符串 字符
-
返回字符在字符串中第一次被查找到時的下標,下標從1開始
-
expr index "$str1" el
-
返回下標2
-
index:指標
-
-
如果查找多個字符在字符串中的位置 返回最先出現的字符的位置
-
-
length 字符串
-
返回字符串的長度
-
expr length "$str1"
-
-
-
-
-
if 分支結構
-
shell中的if語句格式
-
單分支結構
-
if [ test語句 ] then 語句塊 fi
-
-
雙分支結構
-
if [ test語句 ] then 語句塊 else 不滿足條件執行的語句 fi
-
-
多分支結構
-
if [ test語句1 ] then 滿足語句1執行的語句塊 elif [ test語句2 ] ------> elif test 表達式 then 不滿足語句1滿足語句2執行的語句 else 兩個都不滿足語句塊 fi
-
-
-
if對整數進行判斷
-
ARG1 -eq ARG2: ARG1和ARG2相等
-
-eq : INTEGER1 is equal to INTEGER2
-
-
ARG1 -ge ARG2: ARG1>=ARG2
-
-ge : INTEGER1 is greater than or equal to INTEGER2
-
-
ARG1 -gt ARG2: ARG1>ARG2
-
-gt : INTEGER1 is greater than INTEGER2
-
-
ARG1 -le ARG2: ARG1<=ARG2
-
-le : INTEGER1 is less than or equal to INTEGER2
-
-
ARG1 -lt ARG2: ARG1<ARG2
-
-lt : INTEGER1 is less than INTEGER2
-
-
ARG1 -ne ARG2: ARG!=ARG2
-
-ne : INTEGER1 is not equal to INTEGER2
-
-
-
if對字符串進行判斷
-
-n string
-
字符串長度不為零
-
-
-z string
-
字符串長度為零
-
-
str1 = str2
-
str1 != str2
-
-
if對文件進行判斷
-
FILE1 -ef FILE2
-
FILE1 and FILE2 have the same device and inode numbers
-
-
FILE1 -nt FILE2
-
FILE1 is newer (modification date) than FILE2
-
-
FILE1 -ot FILE2
-
-ot :FILE1 is older than FILE2
-
-
-b FILE:文件存在且是一個塊設備文件
-
-c FILE:文件存在且是一個字符設備文件
-
-d FILE:文件存在且是一個目錄設備文件
-
-f FILE:文件存在且是一個普通文件
-
-h\-L FILE:文件存在且為軟鏈接文件
-
lin
-
-
-S FILE:文件存在且是一個套接字文件
-
-e FILE:文件存在
-
equal
-
-
-s FILE:文件存在且大小不為0
-
-p FILE:文件存在且是一個管道文件
-
-w FILE:文件存在且有可寫權限
-
-r FILE:文件存在且有可讀權限
-
-x FILE:文件存在且有可執行權限
-
-
-
case in分支結構
-
格式
-
case $變量名 in 常量1) 語句 ;; 常量2) 語句 ;; ······ 常量n) 語句 ;; *) 語句 esac
-
$變量名
-
通過輸入的變量,進入不同的 “常量)”分支
-
-
;;
-
和C中break的作用相同,shell中必須寫;; (除非是最后一個分支)
-
-
*)
-
起到通配符的作用,可以通配所有情況 shell中*)分支必須是最后一條分支
-
-
-
-
1):如果變量的值為1
-
1|2|3|4): 值為1或2或3或4都走該分支
-
[0-9]):0-9中的值都走該分支 不能寫兩位數,都是對單字符的判斷
-
1?):1開頭兩個字符一個確定一個不確定的情況
-
-
循環結構
-
while循環結構
-
格式
-
while [ test語句 ] do 語句塊 done
-
while [ test語句 ] == while test 表達式
-
[] 中輸入的語句需要用空格與中括號隔開
-
-
-
-
for循環結構
-
shell格式1(類似C語言)
-
類似于C語言的格式 for ((表達式1;表達式2;表達式3)) do 循環體 done
-
執行邏輯和C語言一致
-
-
-
shell格式2(自己的格式)
-
for 變量名 in 字符串列表 do 循環體 done
-
執行邏輯
-
循環變量i從in后面提供的字符串列表中,按順序取值
-
循環次數和字符串列表中字符串的個數有關
-
直到i把字符串列表中每一個字符串的值都獲取結束后,循環結束,(i為獲取的值)
-
-
-
-
使用連續列表的情況
-
seq 起始值 間隔值 終止值
-
終端回顯起始值到終止值之間的數
-
故使用時需用指令置換符
-
-
{1..3}
-
在bash編譯器中遍歷1-3中的每一個數 可以用在for中,單獨使用不能回顯在終端
-
{起始值..終止值}
-
間隔值默認為1
-
中間只能寫兩個點
-
-
-
-
-
select···in循環結構
-
格式
-
select 變量名 in 選項列表 do 語句塊 done
-
-
執行邏輯
-
會在終端打印選項列表 用戶需要根據選項前面的序號做出選擇 選擇后變量會獲取到相應的值 如果用戶不做選擇,會再次打印選項列表 如果用戶選錯,獲取到空值
-
-
常和case語句使用
-
在select···in語句中,嵌套case···in語句, 可以根據用戶的不同選擇,使用case···in完成不同的處理
-
-
-
輔助控制關鍵字
-
break n
-
跳出n層循環
-
-
continu n
-
退出第n層本次循環
-
退出n層本次循環,跳出n層循環時,只需要看第n層循環是否有下一次即可
-
-
-
-
-
shell中的函數
-
格式:(function)函數名() { 函數體 return 返回值 }
-
function 可加可不加
-
shell中的函數仍然滿足先定義后調用
-
shell函數中是否還有返回值,根據實際的實現來決定
-
返回值只能是(0~255)
-
-
調用函數
-
()內必須為空,不能寫任何內容
-
直接通過函數名調用函數
-
函數名
-
fun
-
-
函數調用后其內部的定義變量才能被調用
-
-
如何獲取函數的外部參數
-
如果函數需要外部傳參
-
函數名 參數1 參數2 參數3 ·····
-
fun 12 34
-
調用函數fun
-
-
-
通過外部傳參獲取兩個數,計算兩數和
-
先調用函數,并輸入外部參數
-
-
函數內部仍然通過$獲取外部參數
-
n大于等于10時需用${10}
-
-
函數內部使用$1 $2
-
獲取12和23 兩個外部參數
-
-
在函數外可以訪問函數內的變量(全局變量),但需要函數被調用后訪問
-
函數內和腳本內的外部參數獲取互不影響
-
在函數內使用位置變量,獲取的是函數的外部參數
-
在腳本中使用位置變量,獲取的是腳本的外部參數
-
-
如果想要在函數中,使用腳本的外部參數,只能通過函數調用將該參數傳給函數
-
-
如何獲取函數的輸出
-
函數有返回值
-
$?
-
只能獲取0-255范圍內的值
-
獲取的是上一條指令的運行結果
-
-
-
函數沒有返回值
-
但是函數有echo輸出,可以使用命令置換符獲取
-
·· $()
-
-
-
local
-
修飾局部變量
-
local sum
-
全局變量sum被修飾為局部變量
-
-
-
-