成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

“Exit Trap” 讓你的Bash腳本更穩固可靠

系統 Linux
有個簡單實用的技巧可以讓你的 bash 腳本更穩健 -- 確保總是執行必要的收尾工作,哪怕是在發生異常的時候。要做到這一點,秘訣就是 bash 提供的一個叫做 EXIT 的偽信號,你可以 trap 它,當腳本因為任何原因退出時,相應的命令或函數就會執行。我們來看看它是如何工作的。

[[229272]]

有個簡單實用的技巧可以讓你的 bash 腳本更穩健 -- 確保總是執行必要的收尾工作,哪怕是在發生異常的時候。要做到這一點,秘訣就是 bash 提供的一個叫做 EXIT 的偽信號,你可以 trap 它,當腳本因為任何原因退出時,相應的命令或函數就會執行。我們來看看它是如何工作的。

基本的代碼結構看起來像這樣:

  1. #!/bin/bash
  2. function finish {
  3. # 你的收尾代碼
  4. }
  5. trap finish EXIT

你可以把任何你覺得務必要運行的代碼放在這個 finish 函數里。一個很好的例子是:創建一個臨時目錄,事后再刪除它。

  1. #!/bin/bash
  2. scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
  3. function finish {
  4. rm -rf "$scratch"
  5. }
  6. trap finish EXIT

這樣,在你的核心代碼中,你就可以在這個 $scratch 目錄里下載、生成、操作中間或臨時數據了。注1

  1. # 下載所有版本的 linux 內核…… 為了科學研究!
  2. for major in {1..4}; do
  3. for minor in {0..99}; do
  4. for patchlevel in {0..99}; do
  5. tarball="linux-${major}-${minor}-${patchlevel}.tar.bz2"
  6. curl -q "http://kernel.org/path/to/$tarball" -o "$scratch/$tarball" || true
  7. if [ -f "$scratch/$tarball" ]; then
  8. tar jxf "$scratch/$tarball"
  9. fi
  10. done
  11. done
  12. done
  13. # 整合成單個文件
  14. # 復制到目標位置
  15. cp "$scratch/frankenstein-linux.tar.bz2" "$1"
  16. # 腳本結束, scratch 目錄自動被刪除

比較一下如果不用 trap ,你是怎么刪除 scratch 目錄的:

  1. #!/bin/bash
  2. # 別這樣做!
  3.  
  4. scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
  5.  
  6. # 在這里插入你的幾十上百行代碼
  7.  
  8. # 都搞定了,退出之前把目錄刪除
  9. rm -rf "$scratch"

這有什么問題么?很多:

  • 如果運行出錯導致腳本提前退出, scratch 目錄及里面的內容不會被刪除。這會導致資料泄漏,可能引發安全問題。
  • 如果這個腳本的設計初衷就是在腳本末尾以前退出,那么你必須手動復制粘貼 rm 命令到每一個出口。

  • 這也給維護帶來了麻煩。如果今后在腳本某處添加了一個 exit ,你很可能就忘了加上刪除操作 -- 從而制造潛在的安全漏洞。 

無論如何,服務要在線

另外一個場景: 想象一下你正在運行一些自動化系統運維任務,要臨時關閉一項服務,最后這項服務需要重啟,而且要萬無一失,即使腳本運行出錯。那么你可以這樣做:

  1. function finish {
  2. # 重啟服務
  3. sudo /etc/init.d/something start
  4. }
  5. trap finish EXIT
  6. sudo /etc/init.d/something stop
  7. # 主要任務代碼
  8.  
  9. # 腳本結束,執行 finish 函數重啟服務

一個具體的實例:比如 Ubuntu 服務器上運行著 MongoDB ,你要為 crond 寫一個腳本來臨時關閉服務并做一些日常維護工作。你應該這樣寫:

  1. function finish {
  2. # 重啟服務
  3. sudo service mongdb start
  4. }
  5. trap finish EXIT
  6. # 關閉 mongod 服務
  7. sudo service mongdb stop
  8. # (如果 mongod 配置了 fork ,比如 replica set ,你可能需要執行 sudo killall --wait /usr/bin/mongod”) 

控制開銷

有一種情況特別能體現 EXIT trap 的價值:如果你的腳本運行過程中需要初始化一下成本高昂的資源,結束時要確保把它們釋放掉。比如你在 AWS (Amazon Web Services) 上工作,要在腳本中創建一個鏡像。

(名詞解釋: 在亞馬遜云上的運行的服務器叫“實例”。實例從亞馬遜機器鏡像Amazon Machine Image創建而來,通常被稱為 “AMI” 或 “鏡像” 。AMI 相當于某個特殊時間點的服務器快照。)

我們可以這樣創建一個自定義的 AMI :

  1. 基于一個基準 AMI 運行一個實例(例如,啟動一個服務器)。
  2. 在實例中手動或運行腳本來做一些修改。
  3. 用修改后的實例創建一個鏡像。
  4. 如果不再需要這個實例,可以將其刪除。

最后一步相當重要。如果你的腳本沒有把實例刪除掉,它會一直運行并計費。(到月底你的賬單讓你大跌眼鏡時,恐怕哭都來不及了!)

如果把 AMI 的創建封裝在腳本里,我們就可以利用 trap EXIT 來刪除實例了。我們還可以用上 EC2 的命令行工具:

  1. #!/bin/bash
  2. # 定義基準 AMI ID
  3. ami=$1
  4. # 保存臨時實例的 ID
  5. instance=''
  6. # 作為 IT 人,讓我們看看 scratch 目錄的另類用法
  7. scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
  8. function finish {
  9. if [ -n "$instance" ]; then
  10. ec2-terminate-instances "$instance"
  11. fi
  12. rm -rf "$scratch"
  13. }
  14. trap finish EXIT
  15. # 創建實例,將輸出(包含實例 ID )保存到 scratch 目錄下的文件里
  16. ec2-run-instances "$ami" > "$scratch/run-instance"
  17. # 提取實例 ID
  18. instance=$(grep '^INSTANCE' "$scratch/run-instance" | cut -f 2)

腳本執行到這里,實例(EC2 服務器)已經開始運行 注2。接下來你可以做任何事情:在實例中安裝軟件,修改配置文件等,然后為最終版本創建一個鏡像。實例會在腳本結束時被刪除 -- 即使腳本因錯誤而提前退出。(請確保實例創建成功后再運行業務代碼。) 

更多應用

這篇文章只講了些皮毛。我已經使用這個 bash 技巧很多年了,現在還能不時發現一些有趣的用法。你也可以把這個方法應用到你自己的場景中,從而提升你的 bash 腳本的可靠性。 

尾注

  • 注1. mktemp 的選項 -t 在 Linux 上是可選的,在 OS X 上是必需的。帶上此選項可以讓你的腳本有更好的可移植性。
  • 注2. 如果只是為了獲取實例 ID ,我們不用創建文件,直接寫成 instance=$(ec2-run-instances "$ami" | grep '^INSTANCE' | cut -f 2) 就可以。但把輸出寫入文件可以記錄更多有用信息,便于調試 ,代碼可讀性也更強。 
責任編輯:龐桂玉 來源: Linux中國
相關推薦

2014-06-17 10:02:58

Bash Getopt命令行

2020-04-08 10:21:58

bash腳本語言

2020-04-14 09:22:47

bash腳本技巧

2012-06-15 14:02:51

火狐設置

2018-04-09 08:36:53

敏捷開發云安全基礎設施

2023-08-23 12:12:45

BashLinux

2020-04-26 19:12:29

shell腳本Linux

2023-09-12 23:15:08

Shell腳本

2023-06-19 11:30:19

bashshell

2018-07-11 13:33:56

數據庫MySQL改善經驗

2017-04-13 10:51:17

Bash建議

2018-07-16 09:00:32

LinuxBash數組

2022-05-30 10:31:34

Bash腳本Linux

2016-09-26 14:16:18

shell腳本bash

2025-02-18 07:00:00

SpringBoot開發Java

2016-03-28 09:39:54

2024-11-11 18:04:17

2009-05-04 16:09:04

2021-05-11 07:50:31

BashShell腳本

2010-06-29 14:48:44

SNMP Trap
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费观看a级毛片在线播放 黄网站免费入口 | 欧美日韩久| 在线观看国产精品一区二区 | 99久久免费精品国产男女高不卡 | 国产精品视频yy9299一区 | 国产乱码精品1区2区3区 | 日韩欧美亚洲 | 激情综合五月 | 欧美精品一区二区三区四区 | 婷婷免费视频 | 国产成人久久av免费高清密臂 | 亚洲欧美中文日韩在线v日本 | 婷婷99| 国产美女自拍视频 | 中文字幕一区二区三区不卡在线 | 在线91| 一区二区精品 | 日韩久久久久久 | 黄网站在线观看 | 午夜午夜精品一区二区三区文 | 国产精品 欧美精品 | 狠狠操天天操 | 欧美精品一区二区在线观看 | 免费v片在线观看 | 欧美日韩亚洲国产 | 美女中文字幕视频 | 一级做a爰片久久毛片免费看 | 草b视频 | 精国产品一区二区三区四季综 | 一二三四在线视频观看社区 | 亚洲精品一区二区在线观看 | 香蕉二区 | 亚洲图片视频一区 | 国产精品一区二区久久久久 | 久久免费视频网 | 日韩精品久久一区 | 久久精品久久久 | 国产精品日女人 | 精品一区二区三区四区外站 | 成人精品国产一区二区4080 | 国产探花在线观看视频 |