2013-07-13 72 views
1

我打算在發生故障時使用陷阱執行一些清理代碼。我有以下代碼,但它似乎有一些語法問題。bash中的陷阱語法問題

#!/bin/bash 

set -e 

function handle_error { 
    umount /mnt/chroot 
    losetup -d $LOOP_DEV1 $LOOP_DEV2 
} 

trap "{ echo \"$BASH_COMMAND failed with status code $?\"; handle_error; }" ERR 

是否有人看到陷阱寫入方式的問題。如果發生錯誤,陷阱會被正確執行,但它也會在下面引發另一個不需要的錯誤消息。

/root/myscript.sh: line 60: } ERR with status code 0: command not found 
##line 60 is that line of code that exited with a non zero status 

如何正確寫入以避免錯誤信息?另外,如果我必須將參數$ LOOP_DEV1和$ LOOP_DEV2從主腳本發送到陷阱,然後發送到handle_error函數呢?現在它們被作爲主腳本中的環境變量導出。我做了一些搜索陷阱的例子,但我無法得到類似的東西。

編輯

我從/ bin/sh的爲/ bin/bash的改變的家當。由於/ bin/sh已經符合bash的標準,我沒有想到獨角獸也沒有看到任何東西。

+0

如果腳本實際上是用'sh'而不是'bash'執行的,則需要用'handle_error(){'定義函數。 'function'關鍵字是一個'bash'擴展名。 – chepner

+0

@chepner在大多數情況下,不是/ bin/sh連接到bash的sym鏈接?至少在我的系統中似乎是這種情況。 –

+2

如果你使用Bash語法,那麼你應該在shbang行中指定'#!/ bin/bash',即使'/ bin/sh'是'/ bin/bash'的符號鏈接。那樣的話,如果你的腳本曾經在'/ bin/sh'不是'/ bin/bash'的系統上運行,它仍然可以正常工作。 –

回答

2

該陷阱調用正在創建一個有趣的遞歸,因爲$BASH_COMMAND(和$?)在執行trap命令時正在展開。但是,$BASH_COMMAND在這一點上是陷阱命令本身,文本上包括$BASH_COMMAND(以及一些引號和分號)。其實搞清楚什麼時候陷阱火災是一項有趣的研究要執行的命令,但它不是必要措施來解決這個問題,你可以這樣做:

trap '{ echo "$BASH_COMMAND failed with status code $?"; handle_error; }' ERR 

注意更換"'不僅避免立即進行參數擴展,這也避免了必須逃離內部" s。

+0

似乎正在工作。非常感謝。如果我找出試圖作爲遞歸結果執行的命令,將會發布。 –

+0

@braindead:只要輸入'trap'並查看與ERR關聯的命令是什麼,就可以作弊,儘管您必須仔細查看引號。你會看到它調用了兩次handle_error,但是在兩次調用之間,它試圖執行'「} ERR失敗,狀態碼爲0」',這導致你看到的錯誤信息。請記住'{'和'}'不是自定義字符;我移動了上面的'''使它更加明顯,但'''在'}'之前還是之後沒有區別。 – rici