fnm
fnm copied to clipboard
exec doesn't work for executables other than "node" on Windows
When using fnm exec
, only node
works; npm
and npx
don't execute and so I get my global install (or, no install if fnm is my main way of getting Node).
Here's a PowerShell script which shows what I'm referring to:
if (!(Test-Path -Path fnm-windows)) {
Invoke-WebRequest -URI "https://github.com/Schniz/fnm/releases/download/v1.35.1/fnm-windows.zip" -OutFile "fnm-windows.zip"
Expand-Archive -Path "fnm-windows.zip" -DestinationPath "fnm-windows"
}
$env:FNM_DIR="$PWD/fnm-windows"
echo "fnm install 8"
./fnm-windows/fnm install 8
echo "node --version"
node --version
echo "npm --version"
npm --version
echo "fnm exec --using=8 -- node --version"
./fnm-windows/fnm exec --using=8 -- node --version
echo "fnm exec --using=8 -- npm --version"
./fnm-windows/fnm exec --using=8 -- npm --version
echo 'fnm exec --using=8 -- node -e "console.log(process.env.PATH)"'
./fnm-windows/fnm exec --using=8 -- node -e "console.log(process.env.PATH)"
The output is:
fnm install 8
Installing Node v8.17.0 (x64)
warning: Version already installed at "C:\\Users\\jabaile\\testing/fnm-windows\\node-versions\\v8.17.0"
node --version
v20.8.0
npm --version
10.1.0
fnm exec --using=8 -- node --version
v8.17.0
fnm exec --using=8 -- npm --version
10.1.0
fnm exec --using=8 -- node -e "console.log(process.env.PATH)"
C:\Users\jabaile\testing/fnm-windows\node-versions\v8.17.0\installation;C:\Program Files\PowerShell\7;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Users\jabaile\scoop\apps\python\current\Scripts;C:\Users\jabaile\scoop\apps\python\current;C:\Users\jabaile\go\bin;C:\Users\jabaile\scoop\apps\rustup\current\.cargo\bin;C:\Users\jabaile\scoop\apps\volta\current\appdata\bin;C:\Users\jabaile\scoop\apps\gcc\current\bin;C:\Users\jabaile\scoop\shims;C:\Users\jabaile\AppData\Local\Microsoft\WindowsApps;C:\Users\jabaile\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\jabaile\AppData\Local\Microsoft\WindowsApps;C:\Users\jabaile\AppData\Local\Programs\Microsoft VS Code Insiders\bin
I suspect that something in the chain isn't handling Window's PATHEXT
or something. I'm not super familiar with rust's process handling, but this seems relevant: https://doc.rust-lang.org/std/process/struct.Command.html#platform-specific-behavior
Note on Windows: For executable files with the .exe extension, it can be omitted when specifying the program for this Command. However, if the file has a different extension, a filename including the extension needs to be provided, otherwise the file won’t be found.
So, this is roughly https://github.com/rust-lang/rust/issues/37519 and using https://docs.rs/which/latest/which/ on the command before running would probably fix this. That or, always using a shell on Windows. Not sure what Node itself does here. I know Go handles this for you (https://cs.opensource.google/go/go/+/master:src/os/exec/lp_windows.go), but Rust seems to not want to do this and remain a syscall wrapper.
Note that this probably also affects any other commands run via fnm exec
, since fnm
is running them directly.