Làm thế nào để bảo vệ chức năng bash khỏi bị ghi đè?


12

Trong bashshell, chúng ta có thể định nghĩa một hàm fvới

f(){ echo Hello; }

và sau đó xác định lại / ghi đè lên nó, mà không có bất kỳ thông báo lỗi hoặc cảnh báo nào, với

f(){ echo Bye; }

Tôi tin rằng có một cách để bảo vệ các chức năng khỏi bị ghi đè theo cách này.


2
giống như với các biến, với typeset -r: typeset -rf f.
mosvy

3
hoặcreadonly -f f
mosvy

Câu trả lời:


25

Bạn có thể khai báo flà hàm chỉ đọc bằng cách sử dụng readonly -f fhoặc declare -g -r -f f( readonlytương đương với declare -g -r). Đây là -ftùy chọn cho các tiện ích tích hợp sẵn này khiến chúng hoạt động fnhư tên của một hàm, thay vì trên biến f.

$ f(){ echo Hello; }
$ readonly -f f
$ f(){ echo Bye; }
bash: f: readonly function
$ unset -f f
bash: unset: f: cannot unset: readonly function
$ f
Hello

Như bạn có thể thấy, làm cho chức năng chỉ đọc không chỉ bảo vệ nó khỏi bị ghi đè, mà còn bảo vệ nó khỏi bị hủy đặt (loại bỏ hoàn toàn).


Hiện tại (kể từ bash-5.0.11), cố gắng sửa đổi chức năng chỉ đọc sẽ không chấm dứt hệ vỏ nếu một người đang sử dụng errexittùy chọn shell ( set -e). Chet, người bashbảo trì, nói rằng đây là một sự giám sát và nó sẽ được thay đổi với phiên bản tiếp theo.


Cố gắng ghi đè chức năng tạo thông báo bash: f: readonly functionvà mã trạng thái khác không, nhưng không thoát nếu errexitbật tùy chọn.
kyb

@kyb Tôi nhận thấy điều này là tốt. Tôi không chắc chắn đó là một lỗi trong bash, nhưng tôi sẽ hỏi một trong những bashdanh sách gửi thư để chắc chắn.
Kusalananda

tốt, xin vui lòng cập nhật câu trả lời của bạn khi bạn sẽ chắc chắn về hành vi này.
kyb

1
@kyb Cả Stephane Chazelas và Greg Wooledge đều cân nhắc về câu hỏi đó, cả hai đều có lời giải thích hợp lý. Stephane đề nghị rằng bashchỉ thoát khi set -ecó hiệu lực khi POSIX yêu cầu nó (và readonly -fkhông phải là POSIX). Greg chỉ ra rằng bashhướng dẫn không bao giờ đề cập đến "thất bại trong khai báo hàm" là lý do errexitđể kích hoạt một lối thoát (trừ khi một khai báo hàm được tính là một lệnh ghép, điều mà anh ta khá chắc chắn là không). Chủ đề đang diễn ra ở đây : lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda

@kyb Tôi cũng nhận thấy rằng bạn không bao giờ nói bất cứ điều gì về errexithoặc set -etrong câu hỏi của bạn.
Kusalananda
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.