網站首頁 編程語言 正文
從頭一來二去閱讀語法和命令說明,對于腳本小白來說比較枯燥,難以堅持,所以這里選擇對一份完整的shell腳本代碼來逐行逐段解讀,希望可以渡一渡小白,幫助我們快速進入腳本的大門。
老司機要開車了:
#!/bin/sh
用注釋的形式說明文件打開類型,此處意指本腳本需要用 /bin/sh 打開。
#V1.0?Added?hardware?type?detection #V1.1?xxxx-xx-xx?重構腳本 #V1.2?xxxx-xx-xx?將日志信息輸出到U盤 #V1.3?xxxx-xx-xx?讀取存儲的檢測結果值 #V1.4?xxxx-xx-xx?添加校驗程序版本,U盤下有對應版本信息文件才校驗
上面幾行表示注釋內容。單行注釋,以#
開始
UDiskMountDir=$(df?|?grep?/mnt/sd?|?awk?'END{print?$NF}')
聲明變量 UDiskMountDir 并賦值。
$()
括號內填入命令并執行,最后返回輸出到變量 UDiskMountDir。
df
命令顯示liinux系統上的文件系統磁盤使用情況統計。后邊還可以帶選項,執行更復雜的輸出。命令后邊加 '|' 表示將此命令的輸出作為后邊緊接著的命令的輸入。
grep
命令用于對文本按行搜索然后輸出該行。英文全稱 global search regular expression(RE) and print out the line。grep /mnt/sd
?表示搜索輸入信息里包含?/mnt/sd
的一行,并輸出該行。
awk
命令用于對文本處理,END
表示執行最后的運算或者打印最終的輸出結果,這里用于打印輸出,$NF
?表示列數,print?$NF
?表示打印最后一個字段,各個字段默認以空格劃分,可用選項?-F
指定使用什么字符串來劃分。
LogFile=${UDiskMountDir}/Debug.log
聲明變量 LogFile 并以右邊的內容賦值。將變量 UDiskMountDir 所代表的路徑名與后邊的字符串結合為新的文件名。一般命令中用到的文件名,要不是帶相對路徑的文件名,如?./diretion/filename
,就是帶絕對路徑的文件名,如?/root/diretion/filename
。
${UDiskMountDir}
?表示引用變量 UDiskMountDir 的值。
AllCheckPassed=true
聲明變量 AllCheckPassed 并賦值為true。
AddError() { ????AllCheckPassed=false ????echo?"-200"?>?/tmp/VerCheckRes }
聲明函數 AddError,輸入參數無需聲明。
變量 AllCheckPassed 賦值為true。
echo
命令用于輸出字符串。echo?"-200"?>?/tmp/VerCheckRes
?將 -200 輸出到文件 /tmp/VerCheckRes 并覆蓋原有內容。如果將符號?>
?換成?>>
?則是將內容追加到最后位置。
AddRecord() { ????if?[?!?-d?"/userdata/recordsDir/"?];then ????????mkdir?-p?/userdata/recordsDir/ ????fi ????echo?"$*"?>?/userdata/recordsDir/test ????sync ????AddDebugLog2UDisk?$* }
聲明函數 AddRecord。
if
?表示 if 語句的開始。if[]
方括號內填判斷條件,如為 true 則執行 then 后的語句,否則跳出 if 語句。fi
表示 if 語句的結束。和 C 語言類似,if 語句也可以有?else
?甚至?else if
?(shell 內應該寫成?elif
)。if/elif
?和?then
?如果不在同一行則可以省略符號?;
。if?[?!?-d?"/userdata/recordsDir/"?]
?判斷目錄 /userdata/recordsDir/ 是否存在,并對結果值取反(!
)。
mkdir
命令用于構建目錄。帶選項?-p
表示構建路徑下所有的目錄。mkdir?-p?/userdata/recordsDir/
創建目錄 /userdata/recordsDir/, /userdata/ 如果不存在也會被構建。
echo?"$*"?>?/userdata/recordsDir/test
?將函數輸入的所有參數都輸出到文件 '/userdata/recordsDir/test' 并覆蓋原有內容。'$*' 表示當前函數或者腳本的所有輸入參數,由于在函數內引用,所以這里表示函數的所有輸入參數。
sync
命令用于數據同步。Linux 系統中寫入硬盤的數據往往會被先存放于 buffer 中,這樣是為了效率起見,但是如果系統突然斷電,那么數據就會丟失,這時可以調用 sync 將 buffer 中的數據同步到硬盤。
AddDebugLog2UDisk?$*
?調用函數 AddDebugLog2UDisk 并傳入當前函數(AddRecord)的所有參數。
AddDebugLog2UDisk() { ????echo?"$*"?>>"$LogFile" ????sync }
聲明函數 AddDebugLog2UDisk。
echo?"\$*"?>>"$LogFile"
?表示將函數的所有輸入參數輸出到變量 LogFile 表示的文件中,以追加的形式輸入到文件末尾。
sync
同步數據到硬盤。
#生成下/tmp/App/version.txt版本信息
注釋內容
rm?-f?"$LogFile"
rm
命令用于移除文件。選項?-f
表示強制。rm?-f?"$LogFile"
強制移除變量 LogFile 代表的文件,變量 LogFile 存儲的是文件名,包括路徑。
echo?"0"?>?/tmp/VerCheckRes
輸出字符串 '0' 到文件 /tmp/VerCheckRes
sh?/data/bin/run_normal.sh
在當前的環境中使用另一個shell來執行腳本文件 /data/bin/run_normal.sh,當前環境中變量的值可以在新腳本(/data/bin/run_normal.sh)中被使用(非引用,如果使用 source則變為引用),新腳本文件屬性可以無執行權限。sh
后邊可以帶選項?-n
、-x
等,-n
?用于進行shell腳本的語法檢查,-x
用于實現shell腳本的逐句跟蹤調試并打印該行命令和狀態等。
sleep?2
阻塞當前進程,睡眠 2 秒,和?sleep?2s
?同樣效果。sleep?2h
?表示睡眠 2 小時。
sh?/tmp/App/kill.sh
執行腳本文件 /tmp/App/kill.sh
killall?MachineCheckNode
殺掉進程 MachineCheckNode,MachineCheckNode 為進程名。
lastSNScanResult=$(cat?/userdata/recordsDir/scan)
讀取文件 /userdata/recordsDir/scan 內容并賦值給變量 lastSNScanResult。
cat
命令用于連接文件并輸出內容到標準輸出。
AddDebugLog2UDisk?"last?sn?scan?result:$lastSNScanResult"
調用函數 AddDebugLog2UDisk,并傳遞字符串?last?sn?scan?result:$lastSNScanResult
,$lastSNScanResult
?獲取變量 lastSNScanResult 的值然后和前面的字符串結合成新的字符串。
#檢查SN和markData if?[?!?-f?/data/bin/sysData/sn?];?then? ????AddRecord?"sn?missing" ????AddError else ????snContent=$(cat?/data/bin/sysData/sn) ????AddRecord?"sn?is:$snContent" ????snLen=$(cat?/data/bin/sysData/sn?|?awk?'{print?length($0)}') ????if?[?"$snLen"?!=?"16"?]?;?then ????????AddRecord?"sn?length?error?$snLen" ????????AddError ????fi fi
if?[?!?-f?/data/bin/sysData/sn?]
?判斷文件 /data/bin/sysData/sn 是否是常規文件而且存在,'!' 表示對結果值取反。
如果文件 /data/bin/sysData/sn 找不到或者不是常規文件,則調用后邊的語句塊,直到 else 為止。調用函數 AddRecord(傳入字符串 "sn?missing") 和 AddError(無參數傳入)。
否則,獲取文件內容并賦值給變量 snContent,調用函數 AddRecord(輸入 sn?is:$snContent", 字符串其中會插入變量 snContent 的值);聲明變量 snLen,賦值為命令?cat?/data/bin/sysData/sn?|?awk?'{print?length($0)}'
的執行結果;判斷 snLen 是否不等于 16,是則調用函數 AddRecord 和 AddError。
$(cat?/data/bin/sysData/sn?|?awk?'{print?length($0)}')
?讀取文件 /data/bin/sysData/sn 的內容,通過管道('|')輸入到后一命令語句,awk 計算輸入內容的第一字段的字符長度并輸出。
if?[?!?-f?/data/bin/sysData/markData?];?then? ????AddRecord?"markData?missing" ????AddError fi
判斷文件 /data/bin/sysData/markData 是否不存在,不存在則調用后邊的語句(以 fi 為止)。
#檢驗版本信息 while?read?-r?line?||?[?-n?"${line}"?];?do ????[?"$line"?=?""?]?&&?continue ????item_filename=$(echo?"$line"?|?awk?-F":"?'{print?$1}') ????item_filemd5=$(echo?"$line"?|?awk?-F":"?'{print?$2}') ????if?[?!?-e?"$item_filename"?];?then ????????AddRecord?"$item_filename?missing" ????????AddError ????fi ????acture_md5=$(md5sum?"$item_filename"?|?awk?'{print?$1}') ????if?[?"$item_filemd5"?=?"$acture_md5"?];?then ????????continue ????else ????????AddRecord?"$item_filename"?"md5?diff!?file:"?"$item_filemd5"?"acture:"?"$acture_md5" ????????AddError ????fi done?</tmp/MachineDecDir/check_md5list
while read xxx; do
...done </filename
循環讀取文件名 filename 所指向的文件的內容,每讀取一行存入 xxx 變量。read xxx
為 while 語句的判斷語句,判斷語句和?do
如果不在同一行,則?;
可省略,如:while read xxx
do
...done </filename
read 后邊的?-r
?表示讀取內容過程中對特殊字符有效,如?/
?(輸入未結束需要換行繼續輸入的特殊符號),'/n' 等等。
[?-n?"${line}"?]
?判斷 line 的內容不為空。而前邊的 '||' 表示前一語句?read?-r?line
?返回 false 才執行這個語句。
[?"$line"?=?""?]?&&?continue
?表示如果 line 的內容為空則執行 continue;continue 命令用于跳過當前循環內容回去執行 while 判斷語句。
?item_filename=$(echo?"$line"?|?awk?-F":"?'{print?$1}')
?聲明變量 item_filename 并以后邊語句執行結果賦值。awk?-F":"?'{print?$1}')
?將輸入的內容按照?:
?來劃分字段并輸出第1個字段。awk?-F":"?'{print?$2}')
?則是將輸入的內容按照 ':' 來劃分字段并輸出第2個字段。
if?[?!?-e?"$item_filename"?]
?用于判斷變量 item_filename 代表的文件名所指的文件是否不存在。!
表示取反。if 判斷的內容為 true 則執行 then 后邊的語句,直到 fi 為止,否則跳過。
md5sum?"$item_filename"
?表示計算變量 item_filename 代表的文件名所指的文件的MD5值。
?|?awk?'{print?$1}'
?將前一語句的輸出通過管道連接到后邊的這個語句的輸入,默認按照空格劃分內容并輸出第1個字段內容。
if?[?"$item_filemd5"?=?"$acture_md5"?];?then
?判斷 item_filemd5 和 acture_md5 所代表的內容作為字符串是否一樣,是則執行 then 后的語句。continue 指示程序執行流程直接回到執行 while 判斷語句。else 后的語句塊當 if 的判斷條件不為 true 時執行。
#找到 U 盤路徑 UDiskMountDir=$(df?|?grep?/mnt/sd?|?awk?'END{print?$NF}') #校驗mcu程序版本,U盤下有mcuversion.txt才校驗 UDiskMountDirfile="${UDiskMountDir}/SpecialDir/mcuversion.txt" CurMcuVersionFile="/tmp/mcuversion.txt" if?[?-f?"$UDiskMountDirfile"?];?then ????TargetMcuVersion=$(cat?"$UDiskMountDirfile") ????if?[?-f?"$CurMcuVersionFile"?];?then ????????CurMcuVersion="$(cat?"$CurMcuVersionFile")" ????????if?[?"$TargetMcuVersion"?!=?"$CurMcuVersion"?];?then ????????????AddRecord?"mcuversion?diff?cur:$CurMcuVersion?target:$TargetMcuVersion" ????????????AddError ????????fi ????else ????????AddRecord?"$CurMcuVersionFile?not?found" ????????AddError ????fi fi
UDiskMountDirfile="${UDiskMountDir}/SpecialDir/mcuversion.txt"
?聲明變量 UDiskMountDirfile 并賦值為其后的內容,其后是將變量 UDiskMountDir 所代表的路徑名與后邊的字符串結合為新的文件名。
if 語句可以有多重嵌套,如上。
[?"$TargetMcuVersion"?!=?"$CurMcuVersion"?]
?判斷 TargetMcuVersion 和 CurMcuVersion 所代表的內容是否不相等。
#寫入檢查結果 if?[?$AllCheckPassed?=?"true"?];?then ????AddRecord?"Pass" else ????AddRecord?"Fail" fi
if?[?$AllCheckPassed?=?"true"?];?then
?判斷 AllCheckPassed 的值是否等于字符串 "true",是則調用函數 AddRecord 并傳入參數字符串 "Pass",否則調用函數 AddRecord 并傳入參數字符串 "Fail"。
#啟動checkall /data/bin/Factory/MachineCheckNode?MachineImcomingTest
調用絕對路徑下的程序 MachineCheckNode,并傳入字符串參數 MachineImcomingTest。此種調用方式,要求程序文件 MachineCheckNode 具有可執行的權限屬性x。想要查看指定路徑下所有文件或某個文件的屬性可以使用命令?ls -l
查看,r
表示可讀,w
表示可寫,x
表示可執行。
username@DESKTOP-ABCDEF:/mnt/d/username/work/temp$ ls -l total 0 drwxrwxrwx 1 username username 4096 May 21 16:10 Udisk_IQC
這篇講解到此為止,下期再見!
原文鏈接:https://www.cnblogs.com/englyf/p/16721350.html
相關推薦
- 2022-07-03 kali安裝docker及搭建漏洞環境的詳細教程_docker
- 2022-12-27 React組件間通訊傳值實現詳解_React
- 2022-06-08 .Net?Core?進程守護之Supervisor使用詳解_實用技巧
- 2022-06-21 Android幀式布局實現自動切換顏色_Android
- 2022-06-24 python類名和類方法cls修改類變量的值_python
- 2023-07-28 el-table 默認勾選數據
- 2022-10-15 python?實現syslog?服務器的詳細過程_python
- 2022-12-09 PyTorch中關于tensor.repeat()的使用_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支