我想装饰一些命令(conda
和mamba
在我的情况下),但不是所有命令(所以不像这个Stack Exchange帖子中描述的那样)。
由于这个Stack Exchange答案,我设法为conda
命令做到了这一点,但不是为mamba
命令,通过在我的~/.bashrc
中放入以下内容:
decorate () {
# From https://unix.stackexchange.com/a/125853/457538
eval "_inner_$(typeset -f $1)"
eval "
$1 () {
echo "BEFORE"
_inner_$1 $@
local ret=$?
echo "AFTER"
return $ret
}
"
}
decorate conda
decorate mamba
它适用于conda
而不适用于mamba
,因为此实现依赖于typeset -f $1
以新名称(_inner_$1
)重新复制修饰函数并覆盖原始名称,并且这(typeset -f $1
)仅适用于实际的bash函数(conda
是一个),而不适用于二进制(mamba
是)。
对于mamba
,typeset -f $1
没有返回任何内容,因此当我source ~/.bashrc
时,我从eval "_inner_$(typeset -f $1)"
_inner_: command not found
当我尝试使用装饰的mamba
时,我得到:
~$ mamba
BEFORE
_inner_mamba: command not found
AFTER
所以,我找不到一种通过bash函数修饰二进制命令的方法,我对这个问题的通用解决方案感兴趣。
然而,如果这很重要,我现在的真正目标是在conda
或mamba
执行期间临时修改umask
,然后,如果有针对这种特定情况的替代方法,我也会采用它。
有两个路径-一个用于功能,一个用于命令。记住引用参数——总是引用变量展开。记住引号-你对"
引号的使用是奇怪的,保持一致。简化的概念证明:
decorate () {
if [[ -n "$(typeset -f "$1")" ]]; then
# From https://unix.stackexchange.com/a/125853/457538
eval "_inner_$(typeset -f $1)"
eval "
$1 () {
echo "BEFORE"
_inner_$1 "$@"
local ret=$?
echo "AFTER"
return $ret
}
"
else
eval "
$1 () {
echo "BEFORE"
command $1 "$@"
local ret=$?
echo "AFTER"
return $ret
}
"
fi
}
注意你的命令是非常不安全的-decorate 'rm -r / ; func'
将在eval
内执行并删除所有文件。一定要防止这样的错误。