我已经成功运行了WSL2。在Windows上,我安装了node.js,并希望从Ubuntu层运行npm install snowflake-sdk
。终端返回-bash: /mnt/c/Program Files/nodejs/npm: /bin/sh^M: bad interpreter: No such file or directory
,而PowerShell正常工作。
问题是:是否可以使用WSL2的终端与在Windows上安装的应用程序进行交互?
我已经成功运行了WSL2。在Windows上,我安装了node.js,并希望从Ubuntu层运行npm install snowflake-sdk
。终端返回-bash: /mnt/c/Program Files/nodejs/npm: /bin/sh^M: bad interpreter: No such file or directory
,而PowerShell正常工作。
问题是:是否可以使用WSL2的终端与在Windows上安装的应用程序进行交互?
注:
harzvor 的有用回答提供了良好的背景信息。
虽然不太明显且有些繁琐,但确实可以使从WSL2调用Windows安装的Node.js副本中的npm
工作。您可以将解决方法包装在自定义函数或脚本中:
# From WSL2; note the required use of '.exe'
node.exe 'c:/Program Files/nodejs/node_modules/npm/bin/npm-cli.js' install snowflake-sdk
npm
,使用与CLI入口点在Windows上使用的npm.cmd
批处理文件基本相同的技术。node.exe
而不是 node
。npm
等命令时,Linux子系统将在 $PATH
文件夹中查找该名称的无扩展名文件,这样是行不通的。即使在Windows上实际存在这样的文件,但它是一个基于shebang的脚本,专为类Unix平台设计,实际上在Windows安装中并没有作用,但Linux子系统仍然尝试执行它,因为它使用CRLF(\r\n
)换行符而不是预期的LF-only(\n
)换行符。结果,跟随#!/bin/sh
之后的意外CR(在错误消息中表示为^M
)被认为是可执行路径的一部分,因此调用失败。\\wsl$\Ubuntu-20.04\mnt\c\...
- 这是明确禁止的。npm.cmd
也不起作用,无论是直接调用还是使用cmd.exe /c npm.cmd ...
都不起作用:直接调用*.cmd
文件会失败并且原因难以理解 - 不确定在Windows 10 20H2中是否存在此问题。使用cmd.exe /c
也会失败,因为cmd.exe
不支持UNC路径作为当前目录,并且WSL2内部的当前目录路径总是表达为一个(例如,\\wsl$\Ubuntu-20.04\home\jdoe\project\some-project
)。在这种情况下,cmd.exe
默认为Windows目录,因此无法将包安装到当前WSL目录(项目)中。.js
文件的完整Windows本机路径给node.exe
,可以按预期工作,因为Node.js似乎能够正确处理引用WSL2文件系统目录和文件的UNC路径,例如调用WSL2的shell当前目录。
[1] 在Ubuntu 20.04上,位于shebang行本身的CR字符似乎不再是问题了,但是剩余行中的CR字符仍然会导致调用失败,错误信息更加晦涩,例如:: not foundram Files/nodejs/npm: 3:
。
[2] 原因在于Linux的dirname
工具被用于确定shell脚本所在的目录,以便确定npm-cli.js
的完整路径,而这个工具的设计是从Linux文件系统的角度来操作的,它通过这种间接的、不受支持的方式表达了脚本在Windows文件系统中的位置。
是的,您可以从WSL运行notepad.exe
,它将在Windows中打开记事本。
更多文档:https://learn.microsoft.com/en-us/windows/wsl/interop#run-windows-tools-from-linux
如果我尝试在WSL中运行npm -v
,会出现找不到文件的错误:
PS C:\Users\harvey> bash
harvey@harvey-w10x64-defiance:/mnt/c/Users/harvey$ npm -v
internal/modules/cjs/loader.js:968
throw err;
^
Error: Cannot find module 'C:\mnt\c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
at Function.Module._load (internal/modules/cjs/loader.js:841:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
文件路径基本正确,但是它在末尾添加了C:\mnt
。
我通过向Node提供npm-cli.js
文件的路径来解决这个问题,成功避开了这个问题。
你可以运行:
node.exe \c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js -v
PS C:\Users\harvey> bash
harvey@harvey-w10x64-defiance:/mnt/c/Users/harvey$ cd "/mnt/c/Program Files/nodejs/node_modules/npm/bin"
harvey@harvey-w10x64-defiance:/mnt/c/Program Files/nodejs/node_modules/npm/bin$ ../../../node.exe npm-cli.js -v
6.14.6
从这里开始,我终于能够从NPM CLI得到一些输出了。
从这里开始,我可以安装包,但它可能被安装在错误的位置。
我似乎无法从文件系统的任何地方让npm
工作。这可能是NPM的限制。也许如果你尝试更改路径环境变量,你就可以让它工作?