cmd环境下设置fnm环境变量
主要问题描述
由于项目原因需要经常在windows下切换node环境,找了下FNM资料,没发现合适的文章。所以主要问题就是在不想切换linux环境,也不想用poweshell,还不使用cmder的情况下,每次打开cmd自动设置环境变量。
解决方案:
解决方法1:设置autorun.cmd
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor" /v AutoRun /t REG_SZ /d @^%USERPROFILE^%\autorun.cmd" "2^>NUL /f
打开注册表编辑器(
regedit
)。导航到:
HKEY_CURRENT_USER\Software\Microsoft\Command Processor
如果没有
Autorun
键,右键新建一个String Value
(字符串值),命名为Autorun
。设置值为
C:\path\to\autorun.cmd
(也可以替换为你实际的autorun.cmd
路径)。You can set up a startup script and append the following line:
1 | if defined FNM_ENV ( |
添加一个标记,用来判断是否已经执行过FOR /f "tokens=*" %%i IN ('fnm env --use-on-cd') DO CALL %%i
,防止出现死循环。类似~/.bashrc,每个会话都执行一遍。
解决办法2:设置autorun.cmd
1 | fnm env --use-on-cd > %USERPROFILE%/fnm.txt |
曾经使用了一段时间的方法,缺点是每次都要创建删除文件。
手动执行测试:
1 | FOR /f "tokens=*" %i IN ('fnm env --use-on-cd') DO CALL %i |
错误示范:
1、首先尝试了在批处理里面添加:
FOR /f "tokens=*" %%i IN ('fnm env --use-on-cd') DO CALL %%i
测试结果:无限循环
原因分析:
在autorun.cmd
中使用FOR /f "tokens=*" %%i IN ('fnm env --use-on-cd') DO CALL %%i
时,造成无限循环的原因可能与CALL
命令如何执行命令有关。CALL
命令会执行指定的命令,并且在完成后返回到当前批处理脚本继续执行。如果fnm env --use-on-cd
的输出包含了某个命令,而这个命令在执行时又触发了对autorun.cmd
的调用,就会导致无限循环。
2、尝试直接引用脚本:
1 | :: %CMDER_ROOT%\bin\fnm_init.cmd |
测试结果:无限循环
思维发散
那么问题来了,
1、如何判断cmd是第一次启动呢?
设置环境变量、设置标志文件、读取系统文件进行判断、开机脚本、关机脚本、计划任务……
有空再研究。
2、是否可以固定环境变量呢?
1 | FNM_ARCH=x64 |
应该是可以,假设修改FNM_DIR:
setx /M FNM_DIR "D:\Program Files\npm"
不过这样的话,autorun.cmd的脚本就要更改了,会存在冲突。个人理解,其实只需要设置FNM_MULTISHELL_PATH,其他都可以配置成永久环境变量。
FNM_MULTISHELL_PATH=C:\Users\NAME\AppData\Local\fnm_multishells`29828_1735989106450`这串数字每次都是变化的。
我没有测试,感兴趣的可以自行测试。
总结
本来是个小问题,就是稍微研究研究。可以看到github上的issue,几乎有一半都是跟环境变量有关系(未经严格统计)。懒人症发作,其实不想写的,纠结写还是不写的时间,可能比写下来的时间要久。可见无论要做什么,真正行动起来是最重要的。
参考
fnm/docs/commands.md at master · Schniz/fnm · GitHub
Environment variables need to be setup before you can start using fnm. This is done by evaluating the output of fnm env
.
PowerShell
Add the following to the end of your profile file:
1 | fnm env --use-on-cd --shell powershell | Out-String | Invoke-Expression |
For macOS/Linux, the profile is located at
~/.config/powershell/Microsoft.PowerShell_profile.ps1
For Windows location is either:
%userprofile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
Powershell 5%userprofile%\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
Powershell 6+
To create the profile file you can run this in PowerShell:
1
if (-not (Test-Path $profile)) { New-Item $profile -Force }
To edit your profile run this in PowerShell:
1
Invoke-Item $profile
Windows Command Prompt aka Batch aka WinCMD
fnm is also supported but is not entirely covered. You can set up a startup script for cmd.exe or Windows Terminal and append the following lines:
1 | @echo off |
Usage with Cmder
Usage is very similar to the normal WinCMD install, apart for a few tweaks to allow being called from the cmder startup script. The example assumes that the CMDER_ROOT
environment variable is set to the root directory of your Cmder installation. Then you can do something like this:
- Make a .cmd file to invoke it
1 | :: %CMDER_ROOT%\bin\fnm_init.cmd |
- Add it to the startup script
1 | :: %CMDER_ROOT%\config\user_profile.cmd |
You can replace %CMDER_ROOT%
with any other convenient path too.