從如何編寫冪等Bash指令碼瞭解怎麼實現冪等函式? · Fatih Arslan
當你你寫了一個bash指令碼,但是由於錯誤而執行一半退出了,當您修復了系統中的錯誤並再次執行這個指令碼。但是指令碼中的一半步驟會立即失敗,因為它們已經作用於您的系統了。要構建彈性系統,您需要編寫冪等的軟體。(冪等在分散式環境同樣重要,這樣才能保證重試等正確實現)
什麼是冪等?
冪等指令碼可以多次呼叫,每次呼叫它都會對系統產生相同的影響。這意味著,第二次呼叫將以相同的結果退出,並且不會產生任何副作用:
冪等:表示一個集合的元素,當它自身相乘或以其他方式操作時,其值不變。
良好的軟體總是以冪等方式編寫,特別是如果您在分散式系統中工作,其中操作可能最終是一致性的,並且由於重複請求(例如在具有交付保證的佇列中At-Least-Once),您最終可能會多次呼叫同一個函式。
Bash實現
讓我展示一些bash技巧,可以用來改變你的指令碼為冪等的。
1.建立一個空檔案
這意味著您可以多次呼叫它而不會出現任何問題。第二次呼叫不會對檔案內容產生任何影響。請注意,雖然它會更新檔案的修改時間,但如果您依賴它,請小心。
touch example.txt |
2.建立目錄
切勿直接使用mkdir,而應將其與-p一起使用。如果目錄存在,此標誌確保mkdir不會出錯:
mkdir -p mydir |
3. 建立符號連結
通常做法:
ln -s source target |
但是如果你再次在同一個目標上呼叫它,會失敗。為了使其冪等,傳遞-f:
ln -sf source target |
-f標誌在建立符號連結之前刪除目標符號,因此它將始終成功。
連結目錄時,您也需要傳遞-n。否則再次呼叫它將在目錄中建立一個符號連結。
mkdir a ln -sf a b ln -sf a b ls a a |
所以為了安全起見,請始終使用ln -sfn source target。
4.刪除檔案
傳統:
rm example.txt |
使用-f 忽略不存在的檔案的標誌。
rm -f example.txt |
5.修改檔案
有時您正在向現有檔案新增新的一行。如果再次執行這個指令碼,則需要確保不要再次新增剛才新增的一行。假設你的指令碼這樣:
echo "/dev/sda1 /mnt/dev ext4 defaults 0 0" | sudo tee -a /etc/fstab |
如果再次執行,您最終會有重複的條目/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語句。
(資料庫操作同理)
6.檢查變數,檔案或目錄是否存在
大多數情況下,您會寫入目錄,從檔案讀取或使用變數進行簡單的字串操作。例如,您可能有一個基於某些輸入建立新檔案的工具:
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:file並具有執行許可權
假設您要安裝二進位制檔案,但只有在主機中不存在二進位制檔案時,您才能使用-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並重新執行指令碼,即可輕鬆將二進位制檔案升級到新版本。
7.格式化裝置
要格式化卷,例如ext4格式化,一般使用如下命令:
mkfs.ext4 "$VOLUME_NAME" |
如果再次呼叫它會立即失敗。為了使這個呼叫是冪等的,我們在它前面新增blkid:
blkid "$VOLUME_NAME" || mkfs.ext4 "$VOLUME_NAME" |
此命令列印給定塊裝置的屬性。因此,預先基本上意味著僅在blkid失敗時繼續格式化,這表示給定的卷尚未格式化。
8.安裝裝置
嘗試將卷裝入現有目錄:
mount -o discard,defaults,noatime "$VOLUME_NAME" "$DATA_DIR" |
如果它已經安裝,這將失敗。一種方法是檢查mount命令的輸出並檢視卷是否已經安裝。但是有一種更好的方法可以做到這一點。使用mountpoint命令:
if ! mountpoint -q "$DATA_DIR"; then mount -o discard,defaults,noatime "$VOLUME_NAME" "$DATA_DIR" fi |
總結
從長遠來看,建立冪等且有彈性的軟體總是有益的。因此,瞭解它們是有用的。最近我在bootstrap.sh 指令碼中使用了上述所有提示和技巧 ,用於建立和配置我的遠端開發機器。我知道我可以使用更復雜的工具從頭開始配置VM,但有時候你需要一個簡單的bash指令碼。
相關文章
- 如何編寫冪等的Bash指令碼(函式)? · Fatih Arslan指令碼函式
- 如何編寫冪等的 Bash 指令碼?- Arslan指令碼
- 介面冪等性如何實現?
- 什麼是冪等性?四種介面冪等性方案詳解!
- 【Java面試】什麼是冪等?如何解決冪等性問題?Java面試
- 什麼是冪等
- 冪等最佳實踐
- 答面試官問:怎麼實現介面冪等性面試
- 短影片整套原始碼,如何實現冪等性校驗?原始碼
- 騰訊二面:如何保證介面冪等性?高併發下的介面冪等性如何實現?
- 冪等設計詳解
- 分散式之介面冪等性分散式
- 服務冪等以及常用實現方式
- 在後端中如何實現冪等和去重?後端
- 介面冪等性解決方案
- 冪等性問題
- [java]如何裂解RESTful的冪等性JavaREST
- 如何保證介面的冪等性?
- 建立訂單實現冪等的一點思考
- 在 ASP .NET Core 中實現冪等 REST APIRESTAPI
- 什麼是分散式系統中的冪等性分散式
- 冪等方法的應用
- 再談冪等機制
- 系統冪等設計
- Elasticjob執行job冪等AST
- 什麼是冪等資料管道? - Alaro
- 分散式系統中介面的冪等性分散式
- 短影片app原始碼,實現冪等設計的常見方式APP原始碼
- 聊聊如何實現一個帶冪等模板的Kafka消費者Kafka
- 深入理解冪等技術
- 冪等消費模式 - Pradeep Loganathan模式
- 一對一聊天平臺原始碼,實現冪等的8種方案原始碼
- 分散式冪等問題解決方案三部曲分散式
- 分散式鎖不是控制併發冪等的方式分散式
- 高併發實戰之冪等處理
- 如何保證介面的冪等性?常見的實現方案有哪些?
- 介面服務中的冪等性設計和防重保證,詳細分析冪等性的幾種實現方法
- gRPC重試與介面冪等性RPC