Calling Windows Subsystem for Linux Apps Through Powershell/Cmd

Calling Windows subsystem for Linux apps through PowerShell/cmd

Not yet, according to Windows Blog: Run Bash on Ubuntu on Windows:

Third, note that Bash and Linux tools cannot interact with Windows applications and tools, and vice-versa. So you won’t be able to run Notepad from Bash, or run Ruby in Bash from PowerShell.

More in Microsoft/CommandLine-Documentation#32, which is about the related ability to run win32 commands from within Bash:

Rest assured, we're going to be looking into the interop story in the future, but we won't be adding this capability in the Windows 10 Anniversary Update timeframe.

You might have some luck with the -c option of bash to run specific commands.

How to call Linux commands through WSL in Windows command line?

Apparently this was the most requested feature for WSL, and Microsoft now supports this feature. To use linux commands from within Command Prompt (or PowerShell), just prefix the command with wsl. So, for example, here's how you run ls from CMD.

C:\temp> wsl ls
<- contents of C:\temp ->

Or here's how you update package lists.

C:\temp> wsl sudo apt-get update
[sudo] password for username:
Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [94.5 kB]

More details can be found in the official docs.
I'm not sure if you are looking for a solution which doesn't involve any kind of prefixing. If that's the case, I don't know of any solution yet.

How to call PowerShell script from WSL?

There are two ways to go about this:

  1. You can change your working directory to that of your shell script and execute it normally. To do so, follow these steps:
  • Mount the relevant drive cd /mnt/c/.
  • Change directories according to the path of the script.

  1. This approach is more of a hack that I use for the sake of convenience. I have created a folder in my Windows storage wherein I store all Ubuntu WSL related files. Say, D:\Ubuntu. To avoid changing the working directory every time you open WSL, you can modify the shell profile file (bashrc, zshrc etc.) to load the relevant directory at the end.
  • i.e., Add cd /mnt/d/Ubuntu/ at the end of your ~/.zshrc file if you use zsh or the relevant profile file otherwise.

How to enter Windows-Subsystem-for-Linux (ubuntu) from PowerShell at the current PowerShell working dir

From your Windows Powershell or Powershell Core window, type bash (or wsl); for example:

Sample Image

Now, later versions of Windows include WSL.exe, which replaces bash.exe. The behavior of both executable is the same on my system. The official documentation for wsl.exe states:

Sample Image

You can read that documentation here. Net-net,

I'm running Windows 10 Build-17763. If you aren't experiencing the same behavior I am, you might be running an older version of WSL. You can determine the version of WSL from your build number.

How to start WSL terminal in a current powershell directory?

If we look at what running ubuntu.exe actually does:

PS C:\> ubuntu.exe /?
Launches or configures a Linux distribution.

Usage:
<no args>
Launches the user's default shell in the user's home directory.

install [--root]
Install the distribution and do not launch the shell when complete.
--root
Do not create a user account and leave the default user set to root.

run <command line>
Run the provided command line in the current working directory. If no
command line is provided, the default shell is launched.

config [setting [value]]
Configure settings for this distribution.
Settings:
--default-user <username>
Sets the default user to <username>. This must be an existing user.

help
Print usage information.

We can see that it by default launches the WSL shell inside the home directory. If we want run inside it inside the current directory open in PowerShell, we need to specify the run option. So the full command will be ubuntu.exe run.

Another option is to just run wsl.exe or bash.exe. These commands will by default open WSL in the current working directory.

Note: We don't need to specify the .exe after the commands. Running ubuntu, wsl and bash all work as well. PowerShell knows how to run executables without specifying the extension.

Interact with apps installed on Windows using WSL2

> is it possible to interact with Windows level installed applications using WSL2's terminal?

Yes, you can run notepad.exe from WSL and it will open Notepad in Windows.

More documentation: https://learn.microsoft.com/en-us/windows/wsl/interop#run-windows-tools-from-linux

Solving the NPM issue

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?

Run bash script in WSL through powershell script

.\ubuntu1804.exe by itself opens an interactive shell which PowerShell executes synchronously.

That is, until you submit exit in that interactive shell to terminate it, control won't be returned to PowerShell, so the subsequent commands - cd test_directory and note server.js - are not only not sent to .\ubuntu1804.exe, as you intended, but are then run by PowerShell.

Instead, you must pass the commands to run to .\ubuntu1804.exe via the run sub-command:

.\ubuntu1804.exe run 'cd test_directory; node server.js'

Note: Once node exits, control will be returned to PowerShell.

How do I get Windows 10 Terminal to launch WSL?

You need to do following things first.

1. Install Linux (e.g. Ubuntu)

Search "Ubuntu" in the Microsoft store, then buy and install. This is actually WSL (Windows Subsystem for Linux).

1557633269919

Of course, you want to experience other versions of Linux, as well as Debian:

1557633347262


2. Enable WSL permissions

After installing the WSL version of Linux, you also need to enable WSL permissions:

Open another PowerShell window with "Run as Administrator".

1557633727047

Then enter the following command:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux 

1557633836814

After the command is completed, you can execute the Linux command in the built-out Terminal.

First enter ubuntu in cmd, take a little time to start Ubuntu, set the username and password.

Then you can play with Ubuntu happily. Below I entered a few common commands such as ps, touch, ls etc., as shown below.

1557633540178


3. Change settings

Click "Settings" in right top corner of above image, the file profile.json file will be opened. Then inside the word "profiles" in profile.json file, add below snippet.

        {
"guid": "{78e390db-1bff-4533-9d7c-20f53d8bafa1}",
"name": "WSL",
"colorscheme": "Campbell",
"historySize": 9001,
"snapOnInput": true,
"cursorColor": "#FFFFFF",
"cursorShape": "bar",
"commandline": "wsl ~",
"fontFace": "Consolas",
"fontSize": 12,
"acrylicOpacity": 0.75,
"useAcrylic": true,
"closeOnExit": false,
"padding": "0, 0, 0, 0"
}

Near the word "schemes" in profile.json file, you need to update below:

"schemes": [
{
"name": "Campbell",
"foreground": "#A7B191",
"background": "#0C0C0C",
"colors": [
"#0C0C0C",
"#C50F1F",
"#13A10E",
"#C19C00",
"#0037DA",
"#881798",
"#3A96DD",
"#CCCCCC",
"#767676",
"#E74856",
"#16C60C",
"#F9F1A5",
"#3B78FF",
"#B4009E",
"#61D6D6",
"#F2F2F2"
]
}

The complete setting file (profile.json) which can be obtained here.

Actually, the WSL here is Ubuntu.


4. Add icons to different types of tabs

You can add icons for Tab to this location:

 %LOCALAPPDATA%\packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\RoamingState 

I put some 32x32 PNG in this folder, and then in profile.json I can reference the image resource with the path starting with ms-appdata:// .

The icon is available here:
Icons

Then replace the contents of the new profile-withIcons.json file below with the previous settings.
profile-withIcons.json

After finishing the contents of the folder is like this:

Dir

The final result is:

Icons

How can I run a Windows executable from WSL (Ubuntu) Bash

Native solution

The official solution provided with Windows 10 Insider Preview Update (14951) is based on the almost forgotten binfmt_msc Linux facility for launching binaries. The registration command for the binfmt_misc would be like this (where /init is the provisional binfmt_misc "interpreter" for the win-executables):

sudo echo ":WSLInterop:M::MZ::/init:" > /proc/sys/fs/binfmt_misc/register

And then win-executable would be launched like regular programs:

$ export PATH=$PATH:/mnt/c/Windows/System32
$ notepad.exe
$ ipconfig.exe | grep IPv4 | cut -d: -f2
$ ls -la | findstr.exe foo.txt
$ cmd.exe /c dir

Not that any win-executable must reside in the windows (DrvFs) file-system - not on the Linux's file-system (VolFs) - in order to inherit a proper Windows working-directory.

The cbwin alternative

Untill you get the latest build, project cbwin offers a workaround, by installing 3 new linux commands inside WSL:

  • wcmd: call a win-executable through cmd.exe.
  • wrun: call a win-executable synchronously with CreateProcess, and wait to die (not using cmd.exe).
  • wstart: launch a detached (asynchronously) command (with the use of cmd.exe).

In order to use them, you must:

  1. Install cbwin:

    • a new outbash.exe will be installed in your regular Windows filesystem (somewhere in your %PATH%), plus
    • the 3 linux-commands in the WSL filesystem.
  2. Use this outbash.exe (wherever you installed it) to start WSL, NOT C:\Windows\System32\bash.exe!
  3. Prefix any win-executables with one of those commands, e.g. wrun notepad.

Tip: If the executable launched with wcmd or wrun spawns any children, these survive only for as long that executable remains alive.

In other words, trying to start notepad.exe with wcmd won't work, because notepad will be killed just after having been launched -- Use wrun (synchronously) or wstart (asynchronously) in this case.



Related Topics



Leave a reply



Submit