Como redefinir uma função bash em termos de definição antiga?

13

Existe alguma maneira de redefinir uma função bash em termos de sua antiga definição? Por exemplo, eu gostaria de adicionar o seguinte bloco de código ao preâmbulo da função 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

Atualmente, ele é definido em /etc/profile.d/PackageKit.sh e originado por scripts de inicialização do bash.

Dessa forma, posso consultar o valor de uma variável de ambiente no prompt de comando digitando simplesmente o nome da variável (e desde que não exista esse comando com esse nome). por exemplo

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

Eu sei que poderia copiar e colar a definição atual e adicionar minhas próprias alterações ~/.bashrc, mas estou procurando uma maneira mais elegante que envolva a reutilização de código.

Melhores maneiras de alcançar meu objetivo ou melhorias / extensões de código também são apreciadas.

tmoschou
fonte
Se essa pergunta for mais adequada para o stackoverflow, alguém pode migrá-la, não sei como.
tmoschou
3
Acho que este post no Stack Overflow responde à sua pergunta.
22412 Mat
2
Em vez de eval, você pode usar o indireção:local VAL=$(echo ${!1})
Pausado até novo aviso.

Respostas:

14

Você pode imprimir a definição atual da função e incluí-la em uma definição de função dentro de uma 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
}"

Outra abordagem, que eu acho mais clara, é definir a função original sob um novo nome e chamar isso de sua definição. Isso funciona apenas se você não precisar agir sobre as variáveis ​​locais da definição original.

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  
  original_command_not_found_handle
  
}
Gilles 'SO- parar de ser mau'
fonte
1
Saúde, nunca me ocorreu usar documentos aqui, sem necessidade de citação especial. Acho que prefiro o seu primeiro método, facilita a visualização de toda a definição declare -f, mas gosto da maneira como você renomeia a função original.
tmoschou 23/01/12
0

Obrigado @mat, @ dennis-williamson. Depois de ler seus comentários, é isso que eu recebi

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

Embora eu ache que prefiro a solução @Gilles.

tmoschou
fonte