Làm cách nào để xác định lại hàm bash theo định nghĩa cũ?


13

Có cách nào để tôi có thể định nghĩa lại hàm bash theo định nghĩa cũ của nó không? Ví dụ, tôi muốn thêm khối mã sau vào phần mở đầu của hàm command_not_found_handle (),

# Check if $1 is instead a bash variable and print value if it is
local VAL=$(eval echo \"\$$1\")
if [ -n "$VAL" ] && [ $# -eq 1 ]; then
    echo "$1=$VAL"
    return $?
fi

Nó hiện được định nghĩa trong /etc/profile.d/PackageKit.sh và có nguồn gốc từ các tập lệnh khởi động bash.

Bằng cách đó tôi có thể truy vấn giá trị của biến môi trường tại dấu nhắc lệnh bằng cách nhập tên biến (và với điều kiện là không tồn tại lệnh nào như vậy bởi tên đó). ví dụ

user@hostname ~:$ LANG
LANG=en_AU.utf8

Tôi biết tôi chỉ có thể sao chép và dán định nghĩa hiện tại và thêm các thay đổi của riêng tôi vào ~/.bashrc, nhưng tôi đang tìm kiếm một cách thanh lịch hơn liên quan đến việc sử dụng lại mã.

Những cách tốt hơn để đạt được mục tiêu hoặc cải tiến / mở rộng mã của tôi cũng được đánh giá cao.


Nếu câu hỏi này phù hợp hơn với stackoverflow, ai đó có thể di chuyển nó không, tôi không biết làm thế nào.
tmoschou

3
Tôi nghĩ rằng bài đăng này trên Stack Overflow trả lời câu hỏi của bạn.
Mat

2
Thay vì eval, bạn có thể sử dụng gián tiếp:local VAL=$(echo ${!1})
Tạm dừng cho đến khi có thông báo mới.

Câu trả lời:


14

Bạn có thể in ra định nghĩa hiện tại của hàm và sau đó đưa nó vào định nghĩa hàm bên trong một evalmệnh đề.

current_definition=$(declare -f command_not_found_handle)
current_definition=${current_definition#*\{}
current_definition=${current_definition%\}}
prefix_to_add=$(cat <<'EOF'
  # insert code here (no special quoting required)
EOF
)
suffix_to_add=$(cat <<'EOF'
  # insert code here (no special quoting required)
EOF
)
eval "command_not_found_handle () {
  $prefix_to_add
  $current_definition
  $suffix_to_add
}"

Một cách tiếp cận khác, mà tôi thấy rõ ràng hơn, là xác định hàm gốc dưới một tên mới và gọi nó từ định nghĩa của bạn. Điều này chỉ hoạt động nếu bạn không cần phải hành động theo các biến cục bộ của định nghĩa ban đầu.

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  
  original_command_not_found_handle
  
}

1
Chúc mừng, tôi chưa bao giờ sử dụng tài liệu ở đây, không cần trích dẫn đặc biệt. Tôi nghĩ rằng tôi thích phương pháp đầu tiên của bạn, giúp dễ dàng xem toàn bộ định nghĩa hơn declare -f, nhưng tôi thích cách bạn đổi tên func ban đầu.
tmoschou

0

Cảm ơn @mat, @ dennis-williamson. Sau khi đọc bình luận của bạn, đây là những gì tôi nhận được

eval 'command_not_found_handle () {

    local VAL=$(echo "${!1}")
    if [ -n "$VAL" ] && [ $# -eq 1 ]; then
            echo "$1=$VAL"
            return $?
    fi

    '$(declare -f command_not_found_handle |
    tail -n +3 | head -n -1)'
}'

Mặc dù tôi nghĩ rằng tôi thích giải pháp @Gilles.

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.