Conda in Windows under MSYS2 and Zsh 的問題解決

KpHang發表於2023-03-28

Conda in Windows under MSYS2 and Zsh 的問題解決

在Window11上使用git bash 安裝zsh,並配置p10k主題,主要問題就是prompt中無法顯示conda env;conda activate/deactivate 命令不能正常使用;

總結其實就是一個核心問題,\r,\n,\r\n的區別

Errors likes these:

(eval):11: parse error near ^M 

\r被解析成了^M,導致路徑錯誤,如下:/c/Users/joaom/Miniconda3/Scripts/conda.exe^M

~
❯ conda activate base

~ [base]
❯ conda deactivate

__conda_activate:13: no such file or directory: /c/Users/joaom/Miniconda3/Scripts/conda.exe^M

或者,conda init 無效:

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
If using 'conda activate' from a batch script, change your
invocation to 'CALL conda.bat activate'.

To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - cmd.exe
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.

或者一些其他的報錯,是關於window 和 unix編碼的問題。

參考;

Conda in Windows under MSYS2 and Zsh line ending problems · Issue #9922 · conda/conda (github.com)

Conda activate UnicodeEncodeError if non-ascii characters present in bash prompt · Issue #7876 · conda/conda (github.com)

嘗試過程:

  1. # >>> conda initialize >>>
    # !! Contents within this block are managed by 'conda init' !!
    #if [ -f '/d/Anaconda3/Scripts/conda.exe' ]; then
    #    eval "$('/d/Anaconda3/Scripts/conda.exe' 'shell.zsh' 'hook')"
    #fi
    
    # temp solution
    . /d/Anaconda3/etc/profile.d/conda.sh
    # <<< conda initialize <<<
    
  2. 使用大佬分享的conda.sh檔案;

    export CONDA_EXE=$(echo '/cygdrive/c/Users/karp/anaconda3/Scripts/conda.exe' | tr -d '\r')
    export _CE_M=''
    export _CE_CONDA=''
    export CONDA_PYTHON_EXE='C:\Users\karp\anaconda3\python.exe'
    
    # Copyright (C) 2012 Anaconda, Inc
    # SPDX-License-Identifier: BSD-3-Clause
    
    __add_sys_prefix_to_path() {
        # In dev-mode CONDA_EXE is python.exe and on Windows
        # it is in a different relative location to condabin.
        if [ -n "${_CE_CONDA}" ] && [ -n "${WINDIR+x}" ]; then
            SYSP=$(\dirname "${CONDA_EXE}")
            SYSP=$(echo ${SYSP} | tr -d '\r')
        else
            SYSP=$(\dirname "${CONDA_EXE}")
            SYSP=$(\dirname "${SYSP}")
            SYSP=$(echo ${SYSP} | tr -d '\r')
        fi
    
        if [ -n "${WINDIR+x}" ]; then
            PATH="${SYSP}/bin:${PATH}"
            PATH="${SYSP}/Scripts:${PATH}"
            PATH="${SYSP}/Library/bin:${PATH}"
            PATH="${SYSP}/Library/usr/bin:${PATH}"
            PATH="${SYSP}/Library/mingw-w64/bin:${PATH}"
            PATH="${SYSP}:${PATH}"
            PATH=$(echo ${PATH} | tr -d '\r')
        else
            PATH="${SYSP}/bin:${PATH}"
            PATH=$(echo ${PATH} | tr -d '\r')
        fi
        \export PATH
    }
    
    __conda_exe() (
        __add_sys_prefix_to_path
        $(echo "$CONDA_EXE" | tr -d '\r') $_CE_M $_CE_CONDA $(echo "$@" | tr -d '\r')
    )
    
    __conda_hashr() {
        if [ -n "${ZSH_VERSION:+x}" ]; then
            \rehash
        elif [ -n "${POSH_VERSION:+x}" ]; then
            :  # pass
        else
            \hash -r
        fi
    }
    
    __conda_activate() {
        if [ -n "${CONDA_PS1_BACKUP:+x}" ]; then
            # Handle transition from shell activated with conda <= 4.3 to a subsequent activation
            # after conda updated to >= 4.4. See issue #6173.
            PS1="$CONDA_PS1_BACKUP"
            PS1=$(echo ${PS1} | tr -d '\r')
            \unset CONDA_PS1_BACKUP
        fi
        \local ask_conda
        ask_conda="$(PS1="${PS1:-}" __conda_exe shell.posix "$@")" || \return
        ask_conda=$(echo ${ask_conda} | tr -d '\r')
        \eval "$ask_conda"
        __conda_hashr
    }
    
    __conda_reactivate() {
        \local ask_conda
        ask_conda="$(PS1="${PS1:-}" __conda_exe shell.posix reactivate)" || \return
        ask_conda=$(echo ${ask_conda} | tr -d '\r')
        \eval "$ask_conda"
        __conda_hashr
    }
    
    conda() {
        \local cmd="${1-__missing__}"
        case "$cmd" in
            activate|deactivate)
                __conda_activate $(echo "$@" | tr -d '\r')
                ;;
            install|update|upgrade|remove|uninstall)
                __conda_exe $(echo "$@" | tr -d '\r') || \return
                __conda_reactivate
                ;;
            *)
                __conda_exe $(echo "$@" | tr -d '\r')
                ;;
        esac
    }
    
    if [ -z "${CONDA_SHLVL+x}" ]; then
        \export CONDA_SHLVL=0
        # In dev-mode CONDA_EXE is python.exe and on Windows
        # it is in a different relative location to condabin.
        if [ -n "${_CE_CONDA:+x}" ] && [ -n "${WINDIR+x}" ]; then
            PATH="$(\dirname "$CONDA_EXE")/condabin${PATH:+":${PATH}"}"
        else
            PATH="$(\dirname "$(\dirname "$CONDA_EXE")")/condabin${PATH:+":${PATH}"}"
        fi
        \export PATH
    
        # We're not allowing PS1 to be unbound. It must at least be set.
        # However, we're not exporting it, which can cause problems when starting a second shell
        # via a first shell (i.e. starting zsh from bash).
        if [ -z "${PS1+x}" ]; then
            PS1=
        fi
    fi
    

目前仍然存在的問題是:

雖然conda activate/deactivate 命令不報錯了,但是非base的虛擬環境並未完全啟用;

如下,base env 正常,但其他的env 就不行;(注意*,表示當前啟用環境)

❯ conda activate base
❯ conda env list
# conda environments:
#
base                  *  D:\Anaconda3
d2l                      D:\Anaconda3\envs\d2l

非base env 的情況:(並未啟用;)

❯ conda activate d2l
❯ conda env list
# conda environments:
#
base                     D:\Anaconda3
d2l                      D:\Anaconda3\envs\d2l

後來又找到:https://github.com/conda/conda/issues/9922#issuecomment-1361695031

完美解決。

❯ conda activate d2l
❯ conda env list
# conda environments:
#
base                     D:\Anaconda3
d2l                   *  D:\Anaconda3\envs\d2l

相關文章