使用fvm导致一些CLI工具无法找到flutter命令的解决方案

在使用fvm时由于Flutter命令需要fvm代理,例如使用如下形式:fvm flutter,除非你的环境变量设置了其中一个版本的Flutter SDK的路径,否则直接使用flutter命令会提示找不到命令。并且有些时候会遇到一些令人费解的问题,例如当你在.zshenv文件(如果你使用其他shell,可能是其他的环境变量文件)中设置了正确的Flutter SDK路径,但是尝试运行which dart或者which flutter时发现还是输出错误的位置。本文以macOS下的Zsh为例来解决这个问题,其他shell请自行替换成对应的rc和env文件。

fvm代理flutter命令的问题

一旦你使用fvm进行flutter版本的管理,每次执行flutter命令都必须在前面加一个fvm,写成fvm flutter的形式,诚然,你可以通过alias flutter="fvm flutter"来让使用flutter命令更加便捷,但是这样做对一些CLI工具来说是无效的,例如在使用Riverpod时riverpod_lint工具无法找到对应的flutter命令,并且还可能出现即使鬼使神差地找到了flutter命令,但是使用的flutter和dart并不是对应版本的魔幻情况,至于这个问题,我们在下一个小节再讨论,这里先解决fvm代理flutter的问题。

其实fvm会在用户目录下创建一个~/fvm目录,这个目录下有:

image-20250713115045262

versions子目录中存放的就是所有的Flutter SDK,注意到这里还有个链接文件default,可以看到在上图中,这个链接文件指向的是我本地的3.24.2版本。fvm有一个fvm global <Flutter Version>命令,可以用来设置全局的Flutter版本,而这个default就是指向这个全局版本的。遗憾的是虽然是全局版本,我们还是需要fvm flutter来执行flutter命令,为了解决这一点,我们可以将这个default链接添加到环境变量PATH中!

使用

1
vim ~/.zshenv

打开Zsh的环境配置脚本

为了保证我们环境变量的优先级,建议在最后一样这样进行添加:

62ee645b14224d87fd5e9f6d717ea14e

添加完毕后保存,然后重启终端即可

不要仅尝试使用source ~/.zshenv命令来更新变量,最好还是重启一下,具体原因下一小节解释

重启终端后,使用which dartwhich flutter,如果这俩是来自同一目录下,说明配置生效了,如果这俩还是来自不同目录,请看下一小节

Homebrew或其他包管理器造成的环境变量优先级问题

根据上一小节最后内容,如果你发现dart命令和flutter命令来自不同的目录,并且其中有一方是来自你的Homebrew(或者其他你使用的包管理器目录)的话,说明你遇到了环境变量优先级的问题,首先说明,你之前配置的环境变量是没有问题的,不信可以echo $PATH,确实可以看到我们配置的default目录是在环境变量中的。

Zsh的启动脚本执行顺序

我们在.zshenv中设定环境变量时,还特定将我们的环境变量优先级设置到了最高,可是最后还是遇到了问题,唯一可能的问题就是还有其他地方也往PATH中添加了路径,并且是添加在我们所添加的路径的前面的。

那么Zsh在启动时除了执行我们配置过的.zshenv脚本,还会执行其他脚本吗?会的,其实大多数shell都会根据启动类型来执行不同的脚本,在Zsh中,有以下类型的脚本:

  • .zshenv
  • .zshrc
  • .zprofile
  • .zlogin
  • .zlogout

这些脚本根据打开shell时是否是登录类型来确定是否执行

  • 登录Shell:通过SSH远程打开、通过zsh -l命令打开时为登录shell,此时脚本执行顺序为:.zshenv → .zprofile → .zshrc → .zlogin
  • 非登录Shell:使用图形界面打开、使用zsh命令打开、使用zsh -i命令打开时为非登录Shell,此时脚本的执行顺序为:.zshenv → .zshrc

在平时开发的时候,我们基本都是使用图形化界面打开Shell的,所以基本都是非登录Shell,只需要重点关注.zshenv.zshrc这两个脚本即可。

解决

刚才我们的环境变量被降低了优先级,那肯定就是在.zshrc中发生的,解决方案自然而然,只需要在.zshrc脚本最后添加我们刚才在.zshenv中添加的那行export命令即可,这样就能保证我们的环境变量是最高优先级。

后话

前面我们说不要仅仅只是用source ~/.zshenv来更新Shell变量,这是因为,source命令会重新执行.zshenv脚本,但是却不会执行.zshrc脚本!所以如果.zshrc中有对.zshenv中的环境变量的优先级覆盖行为,运行source ~/.zshenv命令后会发现你似乎配置成功了,但是下一次再打开Shell,变量优先级还是会被覆盖!


使用fvm导致一些CLI工具无法找到flutter命令的解决方案
http://47.109.28.82/2025/07/13/使用fvm导致一些CLI工具无法找到flutter命令的解决方案/
作者
GraftCopolymer
发布于
2025年7月13日
许可协议