问题 正常情况下:
1 2 3 4 5 conda env list base E:\anaconda3
…… …… ……
某天激活环境后突然报错 /System32> conda activate base /System32> conda env list usage: conda-script.py [-h] [-v] [–no-plugins] [-V] COMMAND … conda-script.py: error: argument COMMAND: invalid choice: ‘’ (choose from ‘activate’, ‘clean’, ‘commands’, ‘compare’, ‘config’, ‘create’, ‘deactivate’, ‘env’, ‘export’, ‘info’, ‘init’, ‘install’, ‘list’, ‘notices’, ‘package’, ‘build’, ‘content-trust’, ‘convert’, ‘debug’, ‘develop’, ‘doctor’, ‘index’, ‘inspect’, ‘metapackage’, ‘render’, ‘repoquery’, ‘skeleton’, ‘token’, ‘pack’, ‘server’, ‘repo’, ‘remove’, ‘uninstall’, ‘rename’, ‘run’, ‘search’, ‘update’, ‘upgrade’)
conda读取到的cmd是空字符串''
既然是activate后出现的问题, 那看看conda activate base 到底做了什么
1 2 3 4 5 6 7 8 /System32 > get-command conda CommandType Name Version Source ----------- ---- ------- ------Alias conda -> Invoke-Conda 0 .0 Conda /System32 > (get-command Invoke-Conda ).Definition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 if ($Args .Count -eq 0 ) { & $Env:CONDA_EXE $Env:_CE_M $Env:_CE_CONDA ; }else { $Command = $Args [0 ]; if ($Args .Count -ge 2 ) { $OtherArgs = $Args [1 .. ($Args .Count - 1 )]; } else { $OtherArgs = @ (); } switch ($Command ) { "activate" { Enter-CondaEnvironment @OtherArgs; } "deactivate" { Exit-CondaEnvironment ; } default { & $Env:CONDA_EXE $Env:_CE_M $Env:_CE_CONDA $Command @OtherArgs; } } }
实际上执行的是Enter-CondaEnvironment base
/System32> (get-command enter-condaEnvironment).Definition
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [CmdletBinding ()] param ( [Parameter (Mandatory =$false )][switch ]$Stack , [Parameter (Position =0 )][string ]$Name );begin { If ($Stack ) { $activateCommand = (& $Env:CONDA_EXE $Env:_CE_M $Env:_CE_CONDA shell.powershell activate --stack $Name | Out-String ); } Else { $activateCommand = (& $Env:CONDA_EXE $Env:_CE_M $Env:_CE_CONDA shell.powershell activate $Name | Out-String ); } Write-Verbose "[conda shell.powershell activate $Name ]`n$activateCommand " ; Invoke-Expression -Command $activateCommand ; }process {}end {}
执行的是& $Env:CONDA_EXE $Env:_CE_M $Env:_CE_CONDA shell.powershell activate $Name | Out-String
的输出 把环境变量临时变为空后执行& E:\anaconda3\Scripts\conda.exe shell.powershell activate base | out-string
得到
1 2 3 4 5 6 7 8 9 10 $Env:PATH = "E:\a naconda3;E:\a naconda3\L ibrary\m ingw-w64\b in;E:\a naconda3\L ibrary\u sr\b in;E:\a naconda3\L ibrary\b in;E:\a naconda3\S cripts;E:\a naconda3\b in;E:\a naconda3\c ondabin;." $Env:CONDA_PREFIX = "E:\a naconda3" $Env:CONDA_SHLVL = "1" $Env:CONDA_DEFAULT_ENV = "base" $Env:CONDA_PROMPT_MODIFIER = "(base) " $Env:CONDA_EXE = "E:\a naconda3\S cripts\c onda.exe" $Env:_CE_M = "" $Env:_CE_CONDA = "" $Env:CONDA_PYTHON_EXE = "E:\a naconda3\p ython.exe" . "E:\a naconda3\e tc\c onda\a ctivate.d\o penssl_activate.ps1"
注意这里设置了这两个环境变量
1 2 $Env :_CE_M = "" $Env :_CE_CONDA = ""
此时执行conda env list便报错了 实际执行的命令是: & $Env:CONDA_EXE $Env:_CE_M $Env:_CE_CONDA env list;
由于$Env:_CE_M
$Env:_CE_CONDA
二者均是''
, conda 把’’当做是command, 从而报错.
& $Env:CONDA_EXE ‘’ ‘’ env list; usage: conda-script.py [-h] [-v] [–no-plugins] [-V] COMMAND … conda-script.py: error: argument COMMAND: invalid choice: ‘’ (choose from ‘activate’, ‘clean’, ‘commands’, ‘compare’, ‘config’, ‘create’, ‘deactivate’, ‘env’, ‘export’, ‘info’, ‘init’, ‘install’, ‘list’, ‘notices’, ‘package’, ‘build’, ‘content-trust’, ‘convert’, ‘debug’, ‘develop’, ‘doctor’, ‘index’, ‘inspect’, ‘metapackage’, ‘render’, ‘repoquery’, ‘skeleton’, ‘repo’, ‘pack’, ‘token’, ‘server’, ‘remove’, ‘uninstall’, ‘rename’, ‘run’, ‘search’, ‘update’, ‘upgrade’)
解决方案
修改$Env:_CONDA_ROOT\shell\condabin\Conda.psm1
中定义的Invoke-Conda函数,删掉执行的命令中的$Env:_CE_M $Env:_CE_CONDA
但是不知道这两个环境变量本来有什么用,删除可能会有未知的影响
写到这里的时候google了一下这两个环境变量,直接就搜出了conda项目的两个同样的issue…#14237 #14292 看来bing还是不行啊,搜了半天啥也没搜到
有人指出是pwsh之前的版本'' -eq $null
是True, 所以conda ‘’ ‘’ env list能正常工作 但是7.5.0后是False,所以不行了。
所以算是conda没跟上pwsh产生的一个bug,2024年就修复了, 更新conda即可 conda install conda=25.5.0
最新版conda源码中没有context.dev时,$Env:_CE_M改成了$null
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 def _hook_preamble (self ) -> str : if context.dev: return dedent( f""" $Env:PYTHONPATH = "{CONDA_SOURCE_ROOT} " $Env:CONDA_EXE = "{sys.executable} " $Env:_CE_M = "-m" $Env:_CE_CONDA = "conda" $Env:_CONDA_ROOT = "{CONDA_PACKAGE_ROOT} " $Env:_CONDA_EXE = "{context.conda_exe} " $CondaModuleArgs = @{{ChangePs1 = ${context.changeps1} }} """ ).strip() else : return dedent( f""" $Env:CONDA_EXE = "{context.conda_exe} " $Env:_CE_M = $null $Env:_CE_CONDA = $null $Env:_CONDA_ROOT = "{context.conda_prefix} " $Env:_CONDA_EXE = "{context.conda_exe} " $CondaModuleArgs = @{{ChangePs1 = ${context.changeps1} }} """ ).strip()
体会 善用搜索引擎啊