ohmyzsh遇到(eval):43: defining function based on alias `xxx‘的问题

好想发疯

为什么为什么,kamisama,为什么这种奇怪的bug总要发生在我的身上,呀哒呦呀哒呦,一定是哪里做错了desu,demo…bokuwa真的找到了解决の道啊!不要小看Google的力量啊铁咩(怒音!

TL; DR

ohmyzsh的配置文件里给某个 xxx 定义了一个alias yyy,你在后面又定义了这个 xxx 相关的函数,就会出现这个问题

这里在这个函数调用前加上 unalias xxx 就可以了

问题描述

每次使用ohmyzsh更改了配置以后,执行 source ~/.zshrc 时总会弹出这个警告

(eval):43: defining function based on alias `conda'
(eval):43: parse error near `()'

因为平时用python环境经常用到conda,所以这个配置文件里也会有conda相关的函数,但如果只是简单的函数定义其实是不会有这个问题的,那么问题出在哪呢?

问题溯源

上面的问题,其实是因为除了正常使用conda外,我还给conda链接了一个别名,毕竟每次 conda install 时候配置检查真的是太痛苦了,所以我就转用了 mamba(这里安利一下,貌似很多人都不知道还有这么好用的一个替代库),然后给 conda 起了一个别名,这样我顺手用的时候就直接调用 mamba 了:

alias conda='mamba'

但!!! 如果我也只是起了一个别名就算了,这个错误还是不会发生,这里要提一句,如果你也用conda的话,你会发现你的 .bashrc 或者 .zshrc 或者什么shell的配置文件里有这么一段

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/thinszx/miniconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/thinszx/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/home/thinszx/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/thinszx/miniconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

这里其实每次会调用的脚本是 /home/thinszx/miniconda3/etc/profile.d/conda.sh ,而真正产生问题的也是这个脚本,看一下这个脚本的内容:

export CONDA_EXE='/home/thinszx/miniconda3/bin/conda'
export _CE_M=''
export _CE_CONDA=''
export CONDA_PYTHON_EXE='/home/thinszx/miniconda3/bin/python'

# Copyright (C) 2012 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause

# ...

conda() {
    # ...
}

其实前面的都不重要,我们会发现报错的43行就是 conda() 函数,这里存在的一个问题就是我们定义的alias和函数名重复了,引用GitHub中仓库owner给的解决方案是为了不让这个函数展开,所以把这一行改成标准function写法,但亲身实践并不能解决问题,另一个人给出的方法更合理一点,也比较粗暴,就是在函数调用前把原来定义的alias去掉,这样的话编译器执行函数定义时就没有conda相关的reference了:

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/thinszx/miniconda3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    ##################### 注意这几行
    if alias | grep -q "conda="; then
        unalias conda
    fi
    #####################
    eval "$__conda_setup"
else
    if [ -f "/home/thinszx/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/home/thinszx/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/thinszx/miniconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

alias conda ############### 注意这里

这里会先判断环境中有没有相关的alias,有的话九八环境里的 conda reference给清掉,最后再重新赋回来

原因

懒得找了哈哈哈,不想找了,等我研究生顺利毕业再说吧,有人刷到了记得提醒我(其实下面第一个参考链接说了原因,不过我还没看源码到底是怎么展开的)
写完这篇文章第二天重写了一下,然后就推倒了flag,上面已经给出原因了…

参考

https://github.com/ohmyzsh/ohmyzsh/issues/6723#issue-313463147

https://www.digitalocean.com/community/tutorials/how-to-use-editors-regex-and-hooks-with-z-shell

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值