91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

編寫可靠Bash腳本的技巧有哪些

發布時間:2021-11-04 16:28:30 來源:億速云 閱讀:124 作者:iii 欄目:web開發

這篇文章主要講解了“編寫可靠Bash腳本的技巧有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“編寫可靠Bash腳本的技巧有哪些”吧!

在寫腳本時,在一開始(Shebang 之后)加上下面這一句,或者它的縮略版,能避免很多問題,更重要的是能讓很多隱藏的問題暴露出來:

set -xeuo pipefail

下面說明每個參數的作用,以及一些例外的處理方式 :

-x :在執行每一個命令之前把經過變量展開之后的命令打印出來。

這個對于 debug 腳本、輸出 Log 時非常有用。正式運行的腳本也可以不加。

-e :遇到一個命令失敗(返回碼非零)時,立即退出。

bash 跟其它的腳本語言最大的不同點之一,應該就是遇到異常時繼續運行下一條命令。這在很多時候會遇到意想不到的問題。加上 -e ,會讓 bash  在遇到一個命令失敗時,立即退出。

如果有時確實需要忽略個別命令的返回碼,可以用 || true 。如:

some_cmd || true        # 即使some_cmd失敗了,仍然會繼續運行some_cmd || RET=$?      # 或者可以這樣來收集some_cmd的返回碼,供后面的邏輯判斷使用

但是在管道串起多條命令的情況下,只有最后一條命令失敗時才會退出。如果想讓管道中任意一條命令失敗就退出,就要用后面提到的-o pipefail 了。

加-e 有時候可能會不太方便,動不動就退出。但還是應該堅持所謂的fail-fast  原則,也就是有異常時停止正常運行,而不是繼續嘗試運行可能存在缺陷的過程。如果有命令可以明確忽略異常,那可以用上面提到的 || true  等方式明確地忽略之。

-u :試圖使用未定義的變量,就立即退出。

如果在 bash 里使用一個未定義的變量,默認是會展開成一個空串。有時這種行為會導致問題,比如:

rm -rf $MYDIR/data

如果 MYDIR 變量因為某種原因沒有賦值,這條命令就會變成 rm -rf /data 。這就比較搞笑了。。使用 -u 可以避免這種情況。

但有時候在已經設置了-u 后,某些地方還是希望能把未定義變量展開為空串,可以這樣寫:

${SOME_VAR:-}#  bash變量展開語法,可以參考:https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

-o pipefail :只要管道中的一個子命令失敗,整個管道命令就失敗。

pipefail 與-e 結合使用的話,就可以做到管道中的一個子命令失敗,就退出腳本。

1. 防止重疊運行

在一些場景中,我們通常不希望一個腳本有多個實例在同時運行。比如用 crontab  周期性運行腳本時,有時不希望上一個輪次還沒運行完,下一個輪次就開始運行了。這時可以用 flock 命令來解決。flock  通過文件鎖的方式來保證獨占運行,并且還有一個好處是進程退出時,文件鎖也會自動釋放,不需要額外處理。

用法 1:假設你的入口腳本是 myscript.sh,可以新建一個腳本,通過 flock 來運行它:

# flock --wait 超時時間   -e 鎖文件   -c "要執行的命令" # 例如: flock  --wait 5  -e "lock_myscript"  -c "bash myscript.sh"

用法 2:也可以在原有腳本里使用 flock。可以把文件打開為一個文件描述符,然后使用 flock 對它上鎖(flock  可以接受文件描述符參數)。

exec 123<>lock_myscript   # 把lock_myscript打開為文件描述符123 flock  --wait 5  123 || { echo 'cannot get lock, exit'; exit 1; }

2. 意外退出時殺掉所有子進程

我們的腳本通常會啟動好多子腳本和子進程,當父腳本意外退出時,子進程其實并不會退出,而是繼續運行著。如果腳本是周期性運行的,有可能發生一些意想不到的問題。

在 stackoverflow 上找到的一個方法,原理就是利用 trap 命令在腳本退出時 kill  掉它整個進程組。把下面的代碼加在腳本開頭區,實測管用:

trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT

不過如果父進程是用 SIGKILL (kill -9) 殺掉的,就不行了。因為 SIGKILL 時,進程是沒有機會運行任何代碼的。

3. timeout 限制運行時間

有時候需要對命令設置一個超時時間。這時可以使用 timeout 命令,用法很簡單:

timeout 600s  some_command arg1 arg2

命令在超時時間內運行結束時,返回碼為 0,否則會返回一個非零返回碼。

timeout 在超時時默認會發送 TERM 信號,也可以用 -s 參數讓它發送其它信號。

4. 連續管道時,考慮使用 tee 將中間結果落盤,以便查問題

有時候我們會用到把好多條命令用管道串在一起的情況。如 cmd1 | cmd2 | cmd3 |  ...這樣會讓問題變得難以排查,因為中間數據我們都看不到。

如果改成這樣的格式:

cmd1 > out1.dat cat out1 | cmd2 > out2.dat cat out2 | cmd3 > out3.dat

性能又不太好,因為這樣 cmd1, cmd2, cmd3 是串行運行的,這時可以用 tee 命令:

cmd1 | tee out1.dat | cmd2 | tee out2.dat | cmd3 > out3.dat

感謝各位的閱讀,以上就是“編寫可靠Bash腳本的技巧有哪些”的內容了,經過本文的學習后,相信大家對編寫可靠Bash腳本的技巧有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

登封市| 澄城县| 姜堰市| 东乡族自治县| 静乐县| 霸州市| 庆城县| 中卫市| 鄄城县| 龙陵县| 招远市| 迭部县| 漳州市| 施秉县| 正蓝旗| 南澳县| 资阳市| 申扎县| 新巴尔虎左旗| 岗巴县| 西青区| 屏东县| 阳新县| 犍为县| 南宁市| 新晃| 奉节县| 竹北市| 桐梓县| 兰考县| 灵璧县| 玉田县| 丹巴县| 怀仁县| 巴塘县| 陵川县| 久治县| 双城市| 碌曲县| 海安县| 衡山县|