如何根据旧定义重新定义bash函数?


13

有什么办法可以根据旧定义重新定义bash函数?例如,我想将以下代码块添加到函数的序言中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

它当前在/etc/profile.d/PackageKit.sh中定义,并由bash启动脚本提供。

这样,我可以在命令提示符处通过简单地键入变量名称来查询环境变量的值(并且前提是不存在该名称的此类命令)。例如

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

我知道我可以复制并粘贴当前定义,然后在中添加自己的更改~/.bashrc,但是我正在寻找一种涉及代码重用的更优雅的方法。

也赞赏实现我的目标或代码改进/扩展的更好方法。


如果这个问题更适合stackoverflow,有人可以将其迁移过来,我不知道如何。
tmoschou 2012年

3
我认为有关Stack Overflow的帖子回答了您的问题。
2012年

2
代替eval,您可以使用间接方式:local VAL=$(echo ${!1})
已暂停,直到另行通知。

Answers:


14

您可以打印出函数的当前定义,然后将其包含在eval子句中的函数定义中。

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

我发现更清晰的另一种方法是用新名称定义原始函数,然后从您的定义中调用它。这仅在不需要对原始定义的局部变量进行操作的情况下才有效。

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

1
干杯,我从来没有想过使用here-documents,不需要特殊的报价。我想我更喜欢您的第一种方法,它使使用可以更轻松地查看整个定义declare -f,但是我喜欢重命名原始函数的方式。
tmoschou 2012年

0

谢谢@mat,@ dennis-williamson。看完你的评论,这就是我得到的

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

虽然我认为我更喜欢@Gilles解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.