¿Cómo redefinir una función bash en términos de definición antigua?

13

¿Hay alguna forma de redefinir una función bash en términos de su antigua definición? Por ejemplo, me gustaría agregar el siguiente bloque de código al preámbulo de la función 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

Actualmente está definido en /etc/profile.d/PackageKit.sh y proviene de scripts de inicio de bash.

De esa manera, puedo consultar el valor de una variable de entorno en el símbolo del sistema simplemente escribiendo el nombre de la variable (y siempre que no exista dicho comando con ese nombre). p.ej

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

Sé que podría copiar y pegar la definición actual y agregar mis propios cambios ~/.bashrc, pero estoy buscando una forma más elegante que implique la reutilización del código.

También se aprecian mejores formas de lograr mi objetivo o mejoras / extensiones de código.

tmoschou
fuente
Si esta pregunta sería más adecuada en stackoverflow, ¿alguien puede migrarla? No sé cómo.
tmoschou
3
Creo que esta publicación en Stack Overflow responde a su pregunta.
Mat
2
En lugar de eval, puede usar indirección:local VAL=$(echo ${!1})
pausa hasta nuevo aviso.

Respuestas:

14

Puede imprimir la definición actual de la función y luego incluirla en una definición de función dentro de una evalcláusula.

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

Otro enfoque, que encuentro más claro, es definir la función original con un nuevo nombre y llamarlo desde su definición. Esto solo funciona si no necesita actuar sobre las variables locales de la definición original.

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  
  original_command_not_found_handle
  
}
Gilles 'SO- deja de ser malvado'
fuente
1
Saludos, nunca se me ocurrió usar documentos aquí, no se requiere una cita especial. Creo que prefiero su primer método, hace que sea más fácil ver la definición completa declare -f, pero me gusta la forma en que cambia el nombre de la función original.
tmoschou
0

Gracias @mat, @ dennis-williamson. Después de leer tus comentarios, esto es lo que obtuve

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

Aunque creo que prefiero la solución @Gilles.

tmoschou
fuente