I got my WSL2 up and running. On Windows level I installed node.js and now I want to run npm install snowflake-sdk
from Ubuntu level. Terminal returns -bash: /mnt/c/Program Files/nodejs/npm: /bin/sh^M: bad interpreter: No such file or directory
while PowerShell works fine.
Question is: is it possible to interact with Windows level installed applications using WSL2's terminal?
Note:
npm
on the Linux side , as per the official instructions Thanks, SeaDude . If you then need to call from Windows , you can usewsl npm ...
, but note that cross-file-system calls are generally discouraged in WSL2 . harzvor's helpful answer provides good background information.
It is possible to make calling npm
from a Windows-installed Node.js copy from WSL2 work, though it's not obvious and a bit cumbersome - though you could wrap the workaround in a custom function or script :
# From WSL2; note the required use of '.exe'
node.exe 'c:/Program Files/nodejs/node_modules/npm/bin/npm-cli.js' install snowflake-sdk
The above, which relies on Node.js being installed in its default location on Windows, calls npm
indirectly , using essentially the same technique that the CLI entry point on Windows , the npm.cmd
batch file , uses.
Note:
In order to target a Windows executable from WSL, you must include the filename extension explicitly , such as node.exe
rather than node
.
Without it, eg with npm
, the Linux subsystem looks for an extension-less file by that name in the $PATH
folders, which does not work.
Such a file actually does exist even on Windows, but it is a shebang-based script designed for Unix -like platforms, and basically just dead weight in a Windows installation; the Linux subsystem still tries to execute it, but fails, because it uses CRLF ( \\r\\n
) newlines rather than the expected LF-only ( \\n
) newlines. As a result, the unexpected CR that follows #!/bin/sh
(represented as ^M
in the error message) is considered a part of the executable path , so the invocation fails. [1]
Even fixing that problem manually (converting to LF-only newlines) doesn't help, however, because of how the shell script constructs the full path to the npm-cli.js
entry point : it expresses it as an UNC path that tries to target the Windows file-system location via the WSL file-system - eg,
\\\\wsl$\\Ubuntu-20.04\\mnt\\c\\...
- which is explicitly disallowed . [2]
Calling the batch file, npm.cmd
, explicitly, doesn't work either - neither directly nor with cmd.exe /c npm.cmd ...
:
*.cmd
file fails obscurely - not sure if that's a bug as of Windows 10 20H2.cmd.exe /c
it fails too, because cmd.exe
doesn't support UNC paths as the current directory and the WSL2-internal current directory path is invariably expressed as one (eg, \\\\wsl$\\Ubuntu-20.04\\home\\jdoe\\project\\some-project
).cmd.exe
defaults to the Windows directory in this case, so installation of packages to the current WSL directory('s project) won't work). Providing the full Windows-native path to the npm CLI's main .js
file to node.exe
, as shown above, works as expected , since Node.js seems to otherwise be handling UNC paths that refer to WSL2 file-system directories and files, such as the calling WSL2's shell current directory, properly.
[1] On Ubuntu 20.04, the CR in the shebang line itself no longer seems to be a problem, but the CRs in the remaining lines still are, so the invocation still fails, even more obscurely, which error messages such as : not foundram Files/nodejs/npm: 3:
.
[2] The reason is that the Linux dirname
utility is used to determine the shell script's own directory in order to determine npm-cli.js
's full path, and this utility by design operates from the perspective of the Linux file-system, which ends up expressing the script's Windows file-system location in this indirect, unsupported manner.
Yes, you can run notepad.exe
from WSL and it will open Notepad in Windows.
More documentation: https://docs.microsoft.com/en-us/windows/wsl/interop#run-windows-tools-from-linux
If I try running npm -v
in WSL, I get an error about it not being able to find a file:
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: []
}
The path to the file is mostly correct but it has appended C:\\mnt
to it.
I managed to get around this by running npm
by giving Node the path to the npm-cli.js
file.
You can run:
node.exe \c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js -v
But that runs into the same error.
I then tried this:
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
From here I was finally able to get some output from the NPM CLI.
From here I can install the package but it will likely be installed in the wrong location.
I couldn't seem to get npm
working from anywhere in the filesystem. This may be a limitation with NPM. Perhaps if you try messing with your path env vars, you can get it to work?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.