Come posso ridefinire una funzione bash in termini di vecchia definizione?


13

Esiste un modo per ridefinire una funzione bash in termini di vecchia definizione? Ad esempio, vorrei aggiungere il seguente blocco di codice al preambolo della funzione 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

È attualmente definito in /etc/profile.d/PackageKit.sh e proveniente da script di avvio bash.

In questo modo posso interrogare il valore di una variabile d'ambiente al prompt dei comandi semplicemente digitando il nome della variabile (e purché non esista tale comando con quel nome). per esempio

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

So che potrei semplicemente copiare e incollare la definizione corrente e aggiungere le mie modifiche ~/.bashrc, ma sto cercando un modo più elegante che implichi il riutilizzo del codice.

Sono anche apprezzati modi migliori per raggiungere il mio obiettivo o miglioramenti / estensioni del codice.


Se questa domanda fosse più adatta su StackOverflow, qualcuno può migrarla su, non so come.
tmoschou,

3
Penso che questo post su Stack Overflow risponda alla tua domanda.
Mat

2
Invece di eval, è possibile utilizzare l'indirizzamento indiretto:local VAL=$(echo ${!1})
In pausa fino a nuovo avviso.

Risposte:


14

È possibile stampare la definizione corrente della funzione e quindi includerla in una definizione di funzione all'interno di una evalclausola.

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

Un altro approccio, che trovo più chiaro, è definire la funzione originale con un nuovo nome e chiamarla dalla tua definizione. Funziona solo se non è necessario agire sulle variabili locali della definizione originale.

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

1
Saluti, non mi è mai venuto in mente di usare qui i documenti, non è richiesta alcuna citazione speciale. Penso di preferire il tuo primo metodo, rende più semplice la visualizzazione dell'intera definizione declare -f, ma mi piace il modo in cui rinominare la funzione originale.
Tmoschou,

0

Grazie @mat, @ dennis-williamson. Dopo aver letto i tuoi commenti, questo è quello che ho ottenuto

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

Anche se penso di preferire la soluzione @Gilles.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.