如何編寫冪等的 Bash 指令碼?- Arslan
您編寫了一個 bash 指令碼,但由於錯誤而中途退出,您修復系統中的錯誤並再次執行指令碼。但是指令碼中的一半步驟會立即失敗,因為它們已經應用於您的系統。要構建彈性系統,您需要編寫冪等的軟體。
什麼是冪等性?
冪等指令碼可以被多次呼叫,每次呼叫都會對系統產生相同的影響。這意味著,第二次呼叫將以相同的結果退出並且不會產生任何副作用:
冪等的:表示集合中的一個元素在與自身相乘或以其他方式操作時其值不變。
好的軟體總是以冪等的方式編寫的,尤其是當您在分散式系統中工作時,其中的操作可能最終是一致的,並且您可能會因重複請求(例如在具有At-Least-Once交付保證的佇列中)而多次呼叫函式。
讓我展示一些 bash 技巧和習慣用法,您可以使用它們將指令碼更改為冪等的。您可能正在使用其中的大部分,而沒有意識到副作用:
建立一個空檔案
這是個簡單的。預設情況下,touch是冪等的。這意味著您可以多次呼叫它而不會出現任何問題。第二次呼叫不會對檔案內容產生任何影響。請注意,它會更新檔案的修改時間,因此如果您依賴它,請小心。
touch example.txt
建立目錄
切勿mkdir直接使用,而是與-p標誌一起使用。如果目錄存在,此標誌確保 mkdir 不會出錯:
mkdir -p mydir
建立符號連結
如果你在同一個目標上再次呼叫它,這將失敗。要使其具有冪等性,請傳遞-f標誌:
ln -sf source target
-f標誌在建立符號連結之前刪除目標目的地,因此它總是會成功。
連結目錄時,您也需要傳遞-n。否則再次呼叫它會在目錄中建立一個符號連結。
mkdir a ln -sf a b ln -sf a b ls a a |
因此,為了安全起見,請始終使用ln -sfn source target.
刪除檔案
使用-f 忽略不存在檔案的標誌。
rm -f example.txt
修改檔案
有時您會在現有檔案中新增新行(即:)/etc/fstab。這意味著,如果您執行指令碼,您需要確保不會第二次新增它。
冪等的一種方法是確保通過以下方式檢查grep某些佔位符:
if ! grep -qF "/mnt/dev" /etc/fstab; then echo "/dev/sda1 /mnt/dev ext4 defaults 0 0" | sudo tee -a /etc/fstab fi |
這裡的-q意思是靜默模式和-F啟用fixed string模式。如果/mnt/dev不存在,Grep 將無聲地失敗,因此永遠不會呼叫 echo 語句。
檢查變數、檔案或目錄是否存在
大多數情況下,您正在寫入目錄、讀取檔案或使用變數進行簡單的字串操作。
。例如,您可能有一個基於某些輸入建立新檔案的工具:
echo "complex set of rules" > /etc/conf/foo.txt
計算文字可能是一項昂貴的操作,因此您不想每次呼叫指令碼時都編寫它。為了使其具有冪等性,您可以通過shell的-f的內建test屬性的標誌檢查檔案是否存在:
if [ ! -f "/etc/conf/foo.txt" ]; then echo "complex set of rules" > /etc/conf/foo.txt fi |
-f只是一個示例,您可以使用許多其他標誌,例如:
- -d: 目錄
- -z: 零長度的字串
- -p: 管道
- -x: 檔案並具有執行許可權
假設你想安裝一個二進位制檔案,但只有當它不存在於你的主機中時,你可以使用-x這樣的:
# install 1password CLI if ! [ -x "$(command -v op)" ]; then export OP_VERSION="v0.5.6-003" curl -sS -o 1password.zip https://cache.agilebits.com/dist/1P/op/pkg/${OP_VERSION}/op_linux_amd64_${OP_VERSION}.zip unzip 1password.zip op -d /usr/local/bin rm -f 1password.zip fi |
這會將op二進位制檔案安裝到 /usr/local/bin。如果您重新執行指令碼,它將不再安裝它。另一個好處是,您只需將二進位制檔案從系統中刪除,更新OP_VERSION env 並重新執行指令碼,即可輕鬆將其升級到新版本。
有關完整標誌和運算子的列表,請檢視 man test。
我最近在bootstrap.sh 用於建立和配置遠端開發機器的指令碼中使用了上述所有提示和技巧 。我知道我可以使用更復雜的工具從頭開始配置 VM,但有時一個簡單的 bash 指令碼是您唯一需要的東西。
相關文章
- 如何編寫冪等的Bash指令碼(函式)? · Fatih Arslan指令碼函式
- 從如何編寫冪等Bash指令碼瞭解怎麼實現冪等函式? · Fatih Arslan指令碼函式
- Linux編寫Bash指令碼的10個技巧Linux指令碼
- 編寫更好 Bash 指令碼的 8 個建議指令碼
- 寫出健壯的Bash指令碼指令碼
- 如何編寫高效的 Shell 指令碼指令碼
- 如何寫出安全的、基本功能完善的Bash指令碼指令碼
- 如何使用zx編寫shell指令碼指令碼
- shell 指令碼如何編寫-致初學者指令碼
- Bash指令碼指令碼
- gdb指令碼編寫指令碼
- Shell 指令碼編寫指令碼
- 編譯FFMPEG原始碼的指令碼編寫案例編譯原始碼指令碼
- 如何用 JMeter 編寫效能測試指令碼?JMeter指令碼
- 解析如何在Bash中編寫函式函式
- 如何編寫測試團隊通用的Jmeter指令碼JMeter指令碼
- [20210107]編寫bash shell指令碼遇到的問題.txt指令碼
- 油猴指令碼編寫指令碼
- 編寫git指令碼.shGit指令碼
- 編寫shell指令碼的規範指令碼
- [java]如何裂解RESTful的冪等性JavaREST
- 【Java面試】什麼是冪等?如何解決冪等性問題?Java面試
- EA指令碼編寫要點指令碼
- 編寫執行R指令碼指令碼
- Bash 常用指令碼片段指令碼
- Bash 指令碼簡介指令碼
- bash 指令碼總結指令碼
- 專案啟動指令碼的編寫指令碼
- 介面冪等性如何實現?
- 跟我一起寫shell補全指令碼(Bash篇)指令碼
- 騰訊二面:如何保證介面冪等性?高併發下的介面冪等性如何實現?
- awk命令和指令碼的編寫啟蒙指令碼
- systemd 編寫服務管理指令碼指令碼
- Mac 編寫oracle 連線指令碼MacOracle指令碼
- Linux 指令碼編寫基礎Linux指令碼
- Linux指令碼編寫基礎Linux指令碼
- 批量修改檔名的bash指令碼指令碼
- 世界上最短的bash指令碼指令碼