2013-05-27 29 views
10

Có thể ghi đè lên hàm vỏ và giữ tham chiếu đến hàm gốc không?Ghi đè lên hàm vỏ, giữ tham chiếu đến hàm gốc

f() { echo original; } 
f() { echo wrapper; ...; } 
f 

Sản lượng này sẽ là:

wrapper 
original 

Đây có phải là có thể theo một cách semi-portable?

Lý do: Tôi đang cố gắng kiểm tra chương trình của mình bằng cách thay thế các phần của chương trình bằng chức năng vỏ ghi lại cuộc gọi của họ vào tệp nhật ký. Điều này làm việc tốt miễn là tôi chỉ bọc các lệnh và nội trang, và miễn là tôi không bận tâm đến việc bẻ khóa bừa bãi. Bây giờ tôi muốn làm cho bộ thử nghiệm dễ bảo trì hơn bằng cách chỉ ghi lại phần thú vị trong mỗi bài kiểm tra.

Vì vậy, giả sử chương trình của tôi gồm

f 
g 
h 

nơi f, g, h đều chức năng vỏ, và tôi muốn để theo dõi việc thực hiện các chỉ g.

+0

những gì bạn muốn có thể được thực hiện, nhưng không phải là rất portably. –

Trả lời

3

Nhiều vỏ (zsh, ksh, bash ít nhất) hỗ trợ typeset -f f để đổ nội dung của f(). Sử dụng tính năng này để lưu định nghĩa hiện tại vào một tệp; sau đó, xác định f() như bạn muốn. Khôi phục f() bằng cách tìm nguồn cung cấp tệp được tạo với typeset.

Nếu bạn hơi thay đổi chức năng đổ (đổi tên f()-_f() trên dòng đầu tiên; một chút phức tạp hơn khi f() là đệ quy hoặc gọi chức năng khác mà bạn frobbed trong cùng một cách), bạn có thể có thể có được điều này để sản xuất đầu ra bạn mong muốn.

+0

Một lệnh như vậy: 'declare -f f' Không chắc chắn cái nào là di động hơn ... – anishsane

+0

Cả' typeset' lẫn 'declare' đều là POSIX (Issue 8, 2013). – Jens

+0

@Jens: Bạn có nghĩa là Số phát hành 7 TC1 (phiên bản 2013). Vấn đề 8 chưa được ban hành. :) –

4

Câu trả lời của Jens là chính xác. Chỉ cần thêm mã bên dưới để hoàn thành.

Bạn chỉ có thể sử dụng nó như dưới đây:

eval "`declare -f f | sed '1s/.*/_&/'`" #backup old f to _f 

f(){ 
    echo wrapper 
    _f # pass "[email protected]" to it if required. 
} 

tôi đã sử dụng cùng một logic ở đây: https://stackoverflow.com/a/15758880/793796

+0

+1 cho ý tưởng có eval. – Jens

+1

+1. Tôi cũng sử dụng kỹ thuật này [ở đây] (http://askubuntu.com/questions/73262/how-do-i-teach-bash-in-ubuntu-some-curse-words/73282#73282) –

+0

@glennjackman: I thích ý tưởng của alias_function :) – anishsane

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