Bagaimana cara mendefinisikan ulang fungsi bash dalam definisi lama?

13

Apakah ada cara saya dapat mendefinisikan kembali fungsi bash dalam hal definisi lamanya? Sebagai contoh saya ingin menambahkan blok kode berikut ke mukadimah fungsi 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

Saat ini didefinisikan dalam /etc/profile.d/PackageKit.sh dan bersumber dari skrip start-up bash.

Dengan cara itu saya dapat meminta nilai variabel lingkungan pada prompt perintah dengan hanya mengetikkan nama variabel (dan asalkan tidak ada perintah seperti itu dengan nama itu ada). misalnya

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

Saya tahu saya hanya bisa menyalin dan menempelkan definisi saat ini dan menambahkan perubahan saya sendiri ~/.bashrc, tetapi saya mencari cara yang lebih elegan yang melibatkan penggunaan kembali kode.

Cara yang lebih baik untuk mencapai sasaran atau peningkatan / ekstensi kode saya juga dihargai.

tmoschou
sumber
Jika pertanyaan ini lebih cocok untuk stackoverflow, dapatkah seseorang memindahkannya, saya tidak tahu caranya.
tmoschou
3
Saya pikir posting ini di Stack Overflow menjawab pertanyaan Anda.
Mat
2
Alih-alih eval, Anda dapat menggunakan tipuan:local VAL=$(echo ${!1})
Dijeda sampai pemberitahuan lebih lanjut.

Jawaban:

14

Anda dapat mencetak definisi fungsi saat ini, dan kemudian memasukkannya dalam definisi fungsi di dalam evalklausa.

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
}"

Pendekatan lain, yang saya temukan lebih jelas, adalah mendefinisikan fungsi asli dengan nama baru, dan menyebutnya dari definisi Anda. Ini hanya berfungsi jika Anda tidak perlu bertindak pada variabel lokal dari definisi asli.

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  
  original_command_not_found_handle
  
}
Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Ceria, tidak pernah terjadi pada saya untuk menggunakan dokumen di sini, tidak ada kutipan khusus yang diperlukan. Saya pikir saya lebih suka metode pertama Anda, membuatnya lebih mudah untuk melihat seluruh definisi dengan declare -f, tapi saya suka cara Anda mengganti nama func asli.
tmoschou
0

Terima kasih @mat, @ dennis-williamson. Setelah membaca komentar Anda, inilah yang saya dapatkan

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)'
}'

Meskipun saya pikir saya lebih suka solusi @Gilles.

tmoschou
sumber