วิธีการป้องกันฟังก์ชั่นทุบตีถูกแทนที่?


13

ในbashเปลือกเราสามารถกำหนดฟังก์ชั่นfด้วย

f(){ echo Hello; }

จากนั้นทำการประกาศใหม่ / แทนที่โดยไม่มีข้อผิดพลาดหรือข้อความเตือนใด ๆ ด้วย

f(){ echo Bye; }

ฉันเชื่อว่ามีวิธีในการปกป้องฟังก์ชั่นจากการถูกแทนที่ด้วยวิธีนี้


2
เช่นเดียวกับกับตัวแปรที่มี:typeset -r typeset -rf f
mosvy

3
หรือreadonly -f f
mosvy

คำตอบ:


25

คุณอาจประกาศfว่าเป็นฟังก์ชั่นแบบอ่านอย่างเดียวโดยใช้readonly -f fหรือdeclare -g -r -f f( readonlyเทียบเท่าdeclare -g -r) มันเป็น-fตัวเลือกเหล่านี้ในตัวสาธารณูปโภคที่ทำให้พวกเขาทำหน้าที่เกี่ยวกับชื่อของฟังก์ชั่นที่มากกว่าในตัวแปรff

$ 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

อย่างที่คุณเห็นการทำให้ฟังก์ชั่นอ่านอย่างเดียวไม่เพียง แต่ป้องกันไม่ให้ถูกแทนที่ แต่ยังป้องกันไม่ให้ถูกตั้งค่า (ลบออกทั้งหมด)


ปัจจุบัน (ณbash-5.0.11) การพยายามแก้ไขฟังก์ชั่นแบบอ่านอย่างเดียวจะไม่ยุติเชลล์หากมีการใช้errexitตัวเลือก shell ( set -e) เชษฐ์ผู้bashดูแลบอกว่านี่คือการกำกับดูแลและจะมีการเปลี่ยนแปลงด้วยรุ่นถัดไป


ความพยายามในการแทนที่ฟังก์ชันจะสร้างข้อความbash: f: readonly functionและรหัสสถานะที่ไม่ใช่ศูนย์ แต่จะไม่ออกหากerrexitเปิดใช้งานตัวเลือก
kyb

@kyb ฉันสังเกตเห็นสิ่งนี้เช่นกัน ฉันไม่แน่ใจว่ามันเป็นจุดบกพร่องbashแต่ฉันจะขอให้มีbashรายชื่อผู้รับจดหมายอย่างใดอย่างหนึ่ง
Kusalananda

ดีโปรดอัปเดตคำตอบของคุณเมื่อคุณจะแน่ใจเกี่ยวกับพฤติกรรมนี้
kyb

1
@kyb ทั้ง Stephane Chazelas และ Greg Wooledge ชั่งน้ำหนักในคำถามนั้นทั้งคู่มีคำอธิบายที่น่าเชื่อถือ Stephane แนะนำว่าbashจะออกเมื่อset -eมีผลเมื่อ POSIX ต้องการให้ (และreadonly -fไม่ใช่ POSIX) เกร็กชี้ให้เห็นว่าbashคู่มือไม่เคยกล่าวถึง "ความล้มเหลวในการประกาศฟังก์ชั่น" เป็นเหตุผลในerrexitการทริกเกอร์การออก (เว้นแต่การประกาศฟังก์ชั่นจะนับเป็นคำสั่งผสมซึ่งเขาค่อนข้างมั่นใจว่ามันไม่ได้) เธรดกำลังดำเนินการอยู่ที่นี่: lists.gnu.org/archive/html/help-bash/2019-09/msg00039.html
Kusalananda

@kyb ฉันยังสังเกตเห็นว่าคุณไม่เคยพูดอะไรเกี่ยวกับerrexitหรือset -eในคำถามของคุณ
Kusalananda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.