Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there any way I can redefine a bash function in terms of its old definition? For example I would like to add the following block of code to the preamble of the function 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

It is currently defined in /etc/profile.d/PackageKit.sh and sourced by bash start-up scripts.

That way I can query the value of an environment variable at the command prompt by simply typing the variable name (and provided that no such command by that name exists). e.g.

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

I know I could just copy and paste the current definition and add my own changes in ~/.bashrc, but I am looking for a more elegant way that involves code reuse.

Better ways of achieving my goal or code improvements/extensions are also appreciated.

share|improve this question
    
If this question would be better suited on stackoverflow, can someone migrate it over, I don't know how. –  Tedzdog Jan 22 '12 at 7:16
3  
I think this post on Stack Overflow answers your question. –  Mat Jan 22 '12 at 8:03
2  
Instead of eval, you can use indirection: local VAL=$(echo ${!1}) –  Dennis Williamson Jan 22 '12 at 14:56
add comment

2 Answers

up vote 6 down vote accepted

You can print out the current definition of the function, and then include it in a function definition inside an eval clause.

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

Another approach, which I find clearer, is to define the original function under a new name, and call that from your definition. This only works if you don't need to act on the local variables of the original definition.

eval "original_$(declare -f command_not_found_handle)"
command_not_found_handle () {
  …
  original_command_not_found_handle
  …
}
share|improve this answer
    
Cheers, it never occured to me to use here-documents, no special quoting required. I think I prefer your first method, makes it easier to view the whole definition with declare -f, but I like the way you rename the original func. –  Tedzdog Jan 23 '12 at 6:16
add comment

Thanks @mat, @dennis-williamson . After reading your comments, this is what I got

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

Though I think I prefer @Gilles solution.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.