Bir bash işlevini eski tanım açısından nasıl yeniden tanımlayabilirim?


13

Bir bash işlevini eski tanımı açısından yeniden tanımlamamın bir yolu var mı? Örneğin, işlevin önsözüne aşağıdaki kod bloğunu eklemek istiyorum 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

Şu anda /etc/profile.d/PackageKit.sh dosyasında tanımlanmıştır ve bash başlangıç ​​komut dosyalarından kaynaklanmıştır.

Bu şekilde, yalnızca değişken adını yazarak (ve bu adla böyle bir komutun bulunmaması koşuluyla) bir komut isteminde ortam değişkeninin değerini sorgulayabilirim. Örneğin

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

Sadece geçerli tanımı kopyalayıp yapıştırabildiğimi ve kendi değişikliklerimi ekleyebileceğimi biliyorum ~/.bashrc, ancak kodun yeniden kullanılmasını içeren daha zarif bir yol arıyorum.

Hedefime veya kod geliştirmelerine / uzantılarına ulaşmanın daha iyi yolları da takdir ediliyor.


Bu soru stackoverflow için daha uygun olurdu, birisi onu taşıyabilir, nasıl bilmiyorum.
tmoschou

3
Bence Yığın taşması Bu Mesaja sorunuzu cevaplar.
Mat 22-212

2
Bunun yerine, evaldolaylı olarak kullanabilirsiniz:local VAL=$(echo ${!1})
sonraki duyuruya kadar duraklatıldı.

Yanıtlar:


14

İşlevin geçerli tanımını yazdırabilir ve sonra bir evalyan tümce içindeki bir işlev tanımına ekleyebilirsiniz .

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

Daha net bulduğum bir başka yaklaşım, orijinal işlevi yeni bir ad altında tanımlamak ve bunu tanımınızdan çağırmaktır. Bu yalnızca orijinal tanımın yerel değişkenleri üzerinde işlem yapmanız gerekmiyorsa çalışır.

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

1
Şerefe, buradaki belgeleri kullanmak hiç aklıma gelmedi, özel teklif gerekmiyor. İlk yönteminizi tercih ettiğimi düşünüyorum, tüm tanımı görüntülemeyi kolaylaştırıyor declare -f, ancak orijinal fonk adını yeniden adlandırma şeklinizi seviyorum.
tmoschou

0

Teşekkürler @mat, @ dennis-williamson. Yorumlarınızı okuduktan sonra aldım

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

Sanırım @Gilles çözümünü tercih ediyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.