使用WSL2与安装在Windows上的应用程序进行互动

3 人关注

我的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层安装的应用程序进行交互?

node.js
powershell
terminal
snowflake-cloud-data-platform
windows-subsystem-for-linux
marcin2x4
marcin2x4
发布于 2020-11-09
2 个回答
mklement0
mklement0
发布于 2020-11-09
0 人赞同
  • 更典型的情况是 在Linux端 安装Node.js和 npm ,按照 官方的指示 Thanks, SeaDude .如果你随后需要 从Windows 调用,你可以使用
    wsl npm ... ,但要注意, 在WSL2中一般不鼓励 跨文件系统的调用。
  • 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
    

    上述内容依赖于Node.js安装在Windows的默认位置,间接调用npm ,使用的技术与Windows上的CLI入口--npm.cmd 批处理文件--基本相同。

  • 为了从WSL锁定一个Windows可执行文件,你必须明确包括文件名的扩展名,例如node.exe ,而不是node

  • 如果没有,例如用npm ,Linux子系统就会在$PATH 文件夹中寻找一个无扩展名的文件,这样做是不行的。

  • 这样的文件实际上甚至在Windows上存在,但它是一个为类Unix平台设计的基于shebang的脚本,在Windows安装中基本上只是死物;Linux子系统仍然试图执行它,但失败了,因为它使用CRLF (\r\n)换行,而不是预期的只用LF (\n)换行。结果,#!/bin/sh (在错误信息中表示为^M )后面的意外CR被认为是可执行路径的一部分,所以调用失败。[1]

  • 然而,即使手动解决这个问题(转换为只用LF的换行符)也无济于事,因为shell脚本是如何构建到npm-cli.js 入口点的完整路径的:它将其表达为一个UNC路径,试图通过WSL文件系统来定位Windows文件系统的位置,例如。
    \\wsl$\Ubuntu-20.04\mnt\c\... - 这是被明确禁止的[2]

  • 明确调用批处理文件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目录('s project)不会工作)。
  • 提供npm CLI的主.js 文件的完整的Windows原生路径到node.exe ,如上所示,如预期的那样工作,因为Node.js似乎在其他方面正确地处理引用WSL2文件系统目录和文件的UNC路径,例如调用WSL2的外壳当前目录。

    [1] 在Ubuntu 20.04上,shebang行中的CR似乎不再是个问题,但其余几行中的CR仍然是问题,所以调用仍然失败,甚至更隐蔽,错误信息如: not foundram Files/nodejs/npm: 3:

    [2] 原因是Linux的dirname 工具被用来确定shell脚本自己的目录,以便确定npm-cli.js'的完整路径,而这个工具在设计上是从Linux文件系统的角度来操作的,最终以这种间接的、不支持的方式来表达脚本的Windows文件系统位置。

  • harvzor
    harvzor
    发布于 2020-11-09
    已采纳
    0 人赞同

    > 是否可以使用WSL2的终端与Windows级别安装的应用程序进行交互?

    是的,你可以从WSL运行 notepad.exe ,它将在Windows中打开记事本。

    更多文件 :https://docs.microsoft.com/en-us/windows/wsl/interop#run-windows-tools-from-linux

    解决NPM的问题

    如果我尝试在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 文件的路径来运行npm ,设法解决了这个问题。

    你可以运行。

    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