2016-03-04 14 views
7

Tôi có một kịch bản đơn giản:Làm thế nào để bẫy ERR khi sử dụng 'đặt -e' trong Bash

#!/bin/bash 
set -e 
trap "echo BOO!" ERR 

function func(){ 
    ls /root/ 
} 

func 

Tôi muốn bẫy ERR nếu kịch bản của tôi không (vì nó sẽ ở đây b/c tôi không có quyền xem xét/root). Tuy nhiên, khi sử dụng set -e nó không bị mắc kẹt. Nếu không có set -e ERR bị mắc kẹt.

Theo trang man bash, cho set -e:

... Một cái bẫy trên ERR, nếu được thiết lập, được thực hiện trước khi thoát vỏ. ...

Tại sao bẫy của tôi không được thực thi? Từ trang người đàn ông nó có vẻ như nó nên.

+0

Ngoài ra: tốt hơn là _single-quote_ trình xử lý bẫy của bạn, trừ khi bạn rõ ràng muốn tham chiếu biến trong đó mở rộng _up front_. – mklement0

Trả lời

11

chepner's answer sự là giải pháp tốt nhất: Nếu bạn muốn kết hợp set -e (giống như: set -o errexit) với một cái bẫy ERR, cũng sử dụng set -o errtrace (giống như: set -E).

Nói tóm lại: sử dụng set -eE thay vì chỉ set -e:

#!/bin/bash 

set -eE # same as: `set -o errexit -o errtrace` 
trap "echo BOO!" ERR 

function func(){ 
    ls /root/ 
} 

func 

man bash nói về set -o errtrace/set -E:

Nếu được đặt, bất kỳ cái bẫy trên ERR được thừa hưởng bởi các hàm shell, các lệnh thay thế và các lệnh được thực thi trong môi trường subshell. Bẫy ERR thường không được thừa hưởng trong các trường hợp như vậy.

gì tôi tin rằng đang xảy ra:

  • Without-e: Lệnh ls thất bại trong chức năng của bạn, và, do là lệnh cuối cùng trong chức năng, chức năng báo cáo ls 's mã thoát nonzero cho người gọi, phạm vi kịch bản cấp cao nhất của bạn. Trong phạm vi, bẫy ERR có hiệu lực và được gọi (nhưng lưu ý rằng việc thực thi sẽ tiếp tục, trừ khi bạn gọi rõ ràng exit từ bẫy).

  • Với-e (nhưng không -E): Lệnh ls không bên trong hàm của bạn, và vì set -e có hiệu lực, Bash ngay lập tức lối thoát hiểm, trực tiếp từ phạm vi chức năng - và vì không không có ERR bẫy có hiệu lực (vì nó không được kế thừa từ phạm vi gốc), bẫy của bạn không được gọi.

Trong khi trang man không chính xác, tôi đồng ý rằng hành vi này không rõ ràng - bạn phải phỏng đoán nó.

3

Thay thế ERR bằng EXIT và nó sẽ hoạt động.

Cú pháp của lệnh trap là: trap [COMMANDS] [SIGNALS]

Mọi chi tiết, xin vui lòng đọc http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html

+0

Vậy trang người đàn ông có đúng không? –

+3

Mặc dù đây là một giải pháp khả thi (mặc dù không cần thiết, nếu 'set -o errtrace' được sử dụng), bạn nên đề cập rằng' EXIT' cũng được gọi trong trường hợp kết thúc _successful_, vì vậy bạn cần phải thêm một điều kiện như vậy như 'if [[$? -ne 0]]… 'tới trình xử lý. – mklement0

3

Bạn cần sử dụng set -o errtrace để có chức năng kế thừa bẫy.

Các vấn đề liên quan