Linux-編寫Shell的幾個技巧_02

      網(wǎng)友投稿 977 2025-03-31

      文章目錄


      Pre

      避免重疊運行

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

      timeout 限制運行時間

      連續(xù)管道時, 使用 tee 將中間結(jié)果落盤,以便查問題

      set -x -e -u -o pipefail

      Pre

      Linux-編寫Shell的幾個技巧 繼續(xù)

      避免重疊運行

      在一些場景中,如果不希望一個腳本有多個實例在同時運行。比如用 crontab 周期性運行腳本時,有時不希望上一個輪次還沒運行完,下一個輪次就開始運行了。

      這時可以用 flock 命令來解決。 flock 通過文件鎖的方式來保證獨占運行,并且還有一個好處是進程退出時,文件鎖也會自動釋放,不需要額外處理。

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

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

      1

      2

      3

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

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

      1

      2

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

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

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

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

      1

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

      timeout 限制運行時間

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

      timeout 600s some_command arg1 arg2

      1

      命令在超時時間內(nèi)運行結(jié)束時,返回碼為 0,否則會返回一個非零返回碼。

      timeout 在超時時默認(rèn)會發(fā)送 TERM 信號,也可以用 -s 參數(shù)讓它發(fā)送其它信號。

      連續(xù)管道時, 使用 tee 將中間結(jié)果落盤,以便查問題

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

      如果改成這樣的格式:

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

      1

      2

      3

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

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

      1

      set -x -e -u -o pipefail

      在寫腳本時,在一開始(Shebang 之后)就加上這一句,或者它的縮略版:

      set -xeuo pipefail

      1

      Linux-編寫Shell的幾個技巧_02

      這能避免很多問題,更重要的是能讓很多隱藏的問題暴露出來。

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

      -x : 在執(zhí)行每一個命令之前把經(jīng)過變量展開之后的命令打印出來。

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

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

      bash 遇到異常時繼續(xù)運行下一條命令。 這在很多時候會遇到意想不到的問題。加上 -e 可以讓 bash 在遇到一個命令失敗時,立即退出。

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

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

      1

      2

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

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

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

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

      rm -rf $MYDIR/data

      1

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

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

      ${SOME_VAR:-}

      1

      bash變量展開語法

      https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

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

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

      Linux Shell

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:利用Excel定位函數(shù)判斷員工公積金是否重復(fù)提繳
      下一篇:如何查找和替換文本,然后在Excel中保留格式
      相關(guān)文章
      亚洲av女电影网| 亚洲国产精品无码av| 亚洲视频一区在线| 亚洲国产精品第一区二区| 老司机亚洲精品影视www| 日韩精品亚洲aⅴ在线影院| 亚洲人成网站观看在线播放| 亚洲乱码中文字幕综合234| 亚洲高清成人一区二区三区| 婷婷亚洲天堂影院| 亚洲精品国产电影| 中文字幕亚洲天堂| 永久亚洲成a人片777777| 久久影视国产亚洲| 亚洲综合伊人久久大杳蕉| 亚洲精品无码不卡在线播HE| 中文字幕亚洲综合久久菠萝蜜| 国产成人亚洲精品狼色在线| 亚洲精品午夜无码专区| 日本亚洲欧洲免费天堂午夜看片女人员 | 亚洲一卡二卡三卡| 亚洲综合中文字幕无线码| 亚洲熟女www一区二区三区| 亚洲国产综合AV在线观看| 久久人午夜亚洲精品无码区| 亚洲国产成人久久综合区| 综合亚洲伊人午夜网 | 亚洲卡一卡2卡三卡4卡无卡三| 亚洲黄色在线观看| 久久精品国产亚洲AV忘忧草18| 亚洲精品456人成在线| 亚洲成a人片在线观看天堂无码| 色婷婷亚洲一区二区三区| 国产偷窥女洗浴在线观看亚洲| 亚洲情综合五月天| 久久亚洲AV成人出白浆无码国产| 亚洲精品白色在线发布| 亚洲真人无码永久在线观看| 亚洲JIZZJIZZ中国少妇中文| 国产亚洲AV无码AV男人的天堂| 亚洲福利一区二区三区|