Bash

在 shell 命令(不是腳本)中獲得“確保”/“最終”功能?

  • June 13, 2017

我需要知道一個命令是成功還是失敗,然後無條件地執行一些清理。

執行順序命令的正常選項似乎都不適用於此處:

$ mycmd.sh && rm -rf temp_files/    # correct exit status, cleanup fails if mycmd fails
$ mycmd.sh ;  rm -rf temp_files/  # incorrect exit status, always cleans up
$ mycmd.sh || rm -rf temp_files/    # correct exit status, cleanup fails if mycmd succeeds

如果我要在 shell 腳本中執行此操作,我會執行以下操作:

#!/usr/bin/env bash
mycmd.sh
RET=$?
rm -rf temp_files
exit $RET

有沒有比用分號將所有這些命令連結在一起更慣用的方法來在命令行上完成它?

腳本中的換行符幾乎總是等同於分號:

mycmd.sh; ret=$?; rm -rf temp_files; exit $ret

回應編輯:

或者,您也可以使用 atrap和一個子外殼:

( trap 'rm -rf temp_files' EXIT; mycmd.sh )

如果您正在尋找某些語言的副本try { } finally { },還有另一種方法:使用trap內置bash和其他 POSIXy shell(請參閱 參考資料help trap)。

#!/bin/bash

# exit with this by default, if it is not set later
exit_code=0  

# the cleanup function will be the exit point
cleanup () {
 # ignore stderr from rm incase the hook is called twice
 rm -rf "temp_files/" &> /dev/null  
 # exit(code)
 exit $exit_code
}

# register the cleanup function for all these signal types (see link below)
trap cleanup EXIT ERR INT TERM

# run your other script
mycmd.sh

# set the exit_code with the real result, used when cleanup is called
exit_code=$?

閱讀陷阱命令的參數。

注意cleanup被稱為:

  • 如果發送此腳本 SIGINT 或 SIGTERM 或者如果按下 CTRL-C (SIGINT)
  • 如果此腳本以 0 正常退出
  • 如果 mycmd.sh 以非零狀態退出(可能不是您想要的——**從陷阱的參數中****刪除ERR**為 disable )

引用自:https://unix.stackexchange.com/questions/369382