是否可以保存旧函数(名为foo
),以便您可以在新函数(也称为foo
)中调用它,可能来自不同的名称,或者?
为了使这个具体化,这里特别是我正在尝试做的事情:
在bash中,command_not_found_handle
是一个函数,如果定义了,只要bash找不到用户试图运行的命令就会调用它。例如,Ubuntu使用它来建议可以安装的软件包:
$ pv
The program 'pv' is currently not installed. You can install it by typing:
sudo apt-get install pv
这真是很好,我想保持这种行为。但是,我还喜欢添加另一个command_not_found
句柄,它只是使用用户输入的任何命令行运行给定的DEFAULT_COMMAND
,如下所示:
$ DEFAULT_COMMAND=git
$ status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working
directory)
modified: .bashrc
modified: .gitconfig
modified: .vimrc
Untracked files:
(use "git add <file>..." to include in what will be committed)
.bash_profile
.gitglobalignore
.gvimrc
node_modules/
no changes added to commit (use "git add" and/or "git commit -a")
我已经有了上述功能,它就像一个梦想;但是,使用它覆盖默认的Ubuntu command_not_found
句柄,当我不记得给定可执行文件的包名时,它可以很方便。
我如何同时获得两者?谢谢!
注意:显而易见的解决方案是在我的脚本中查找并复制Ubuntu内置command_not_found
逻辑;但这并不理想,因为这意味着我必须在以后手动更新它,当Ubuntu改变他们做事的方式时。如果可能的话,我希望有更通用的东西。
编辑:最好不要诉诸字符串操作,可以通过将函数的 text 保存到变量,修改它,然后eval
来完成它
答案 0 :(得分:1)
根据Barmar的建议,我能够实现可行的 解。以下函数可用于重命名任意 bash函数改为其他名称。
renameFunction () {
local oldName="$1"; shift
local newName="$1"
local definition="$(declare -f "$oldName")"
if [[ $? -gt 0 ]]; then
echo >&2 "renameFunction: $oldName is not a function"
return
fi
if declare -f "$newName" >/dev/null 2>/dev/null; then
echo >&2 "renameFunction: $newName is already defined"
return
fi
eval "$(echo "${definition/"$oldName"/"$newName"}")"
# Does not work for recursive functions (like "//" would), but also
# doesn't break if $oldName is a substring of something else
unset "$oldName"
}
最后一行
unset "$oldName"
是可选的 - 没有它,它就变成了“复制功能”实用程序。
模式替换适用于递归函数(如果是)
更改为以下内容(请注意//
):
eval "$(echo "${definition//"$oldName"/"$newName"}")"
但是,如果函数名是某个子字符串,则会失败 在定义中的其他内容。由于递归在shell中比较少见 脚本,我采取了不那么脆弱的方法。
引用正确,尽管对于SO语法过于复杂
荧光笔。 (引用也是不必要的,除非你喜欢
与$IFS
一起玩。)
为了完整起见,以下是我使用此功能的方法:
# The DEFAULT_CMD is the command to run if the command line could
# not be understood. Set the DEFAULT_CMD to git, once; the user can
# change it at any time
DEFAULT_CMD=git
# Save the old command_not_found_handle for reuse
renameFunction command_not_found_handle __PREVIOUS_COMMAND_NOT_FOUND_HANDLE
command_not_found_handle () {
eval '"$DEFAULT_CMD" $DEFAULT_CMD_PREFIX_ARGS "$@" $DEFAULT_CMD_POSTFIX_ARGS'
if [ $? -gt 0 ]; then
__PREVIOUS_COMMAND_NOT_FOUND_HANDLE "$@"
fi
}
export DEFAULT_CMD
只要找不到,command_not_found_handle
就会调用{p> bash
用户指定的程序或命令。它接收它作为它的论据
整个命令行。
此函数尝试将命令行作为“子命令”执行
给定的DEFAULT_CMD
。如果它没有成功,它会尝试旧的
command_not_found_handle