How do I use Bash on Ubuntu on Windows (WSL) for my VS Code terminal?

66,913

Solution 1

This answer seeks to help others avoid spending 1-2 hours troubleshooting and slowly finding disparate solutions for common problems when using WSL for the terminal in VS Code. It does not cover installing specific packages, but rather common ones that may not properly install as dependencies when installing things that do rely on their presence, and on fixing related common settings.

Summary of steps

  • WSL installed
  • VS Code (or other IDE) configured for terminal
  • NPM installed & path fix in .profile (may help with other tools)
  • build-essential installed (helps with any tools that use make/gcc/etc)
  • VS Code Tasks using WSL
  • Extras

Getting Started & Requirements

  • You must have WSL installed. (Which means you must be running 64 bit Windows 10, with the appropriate updates) Follow the install guide if not already installed. This will require some reboots.

VS Code Terminal Configuration

Either the CTRL+, keyboard shortcut, or FilePreferencesSettings

In the top right of the editing window, make sure you are working in the correct context for you: either User Settings or Workspace Settings.

enter image description here

In the settings search bar, type terminal.integrated.shell.windows (or whatever gets you far enough long)

Find the setting in the actual settings file, use Edit (mouse over the line, it will be on the left: on a touch screen without a mouse, you should be able to simply tap to the left of the line), and select Replace in Settings

enter image description here

In the right pane, modify the entry created in the modified json file: replace the previous setting with

"C:\\WINDOWS\\Sysnative\\bash.exe"

enter image description here

Other IDEs: IntelliJ

Open Settings/Tools/Terminal and set the "Shell path" field to "C:\Users\USERNAME\AppData\Local\Microsoft\WindowsApps\ubuntu.exe"

Making your WSL Ubuntu Bash Terminal functional for dev

When you use CTRL+` to open the terminal, you should now have a bash terminal.

If this is the first time you have run bash.exe, you may be asked about installing Ubuntu. Do so. Once your installation is complete, choose your username and password to be used in WSL Ubuntu. These do not have to coincide with your current Windows account, and it's important to note that they will not change based on changes to your Windows account's password.

Once you are done, you will have a bash command prompt in your terminal.enter image description here

Note that unlike git-bash on Windows, this is a separate environment. While it can be used to launch Windows software outside of itself, you will need appropriate Ubuntu packages to run them within the actual terminal.

Currently, WSL does not come loaded with everything you might expect or be used to having, and some things can conflict with software you have loaded in Windows, based on default profile settings.

Updates & git

Note: I'm going to document these as sudo for people who simply need single pieces of this, but one option at the start is to instead sudo su and simply running the following commands without sudo.

Make sure your Ubuntu packages are up to date:

sudo apt-get -y update
sudo apt-get -y upgrade
sudo apt-get -y dist-upgrade
sudo apt autoremove

Install git:

sudo apt-get install git

Node.js & NPM

If you already have Node or NPM loaded in Windows, running them in Ubuntu can get problematic due to path issues. So, you need to install the Ubuntu native versions and ensure that they are used instead.

First, install node.js with NPM. (alternate: install NVM and use it to install node.js)

After installing, running npm commands will probably fail: for example, npm -v will probably give you:

: not foundram Files/nodejs/npm: 3: /mnt/c/Program Files/nodejs/npm:
: not foundram Files/nodejs/npm: 5: /mnt/c/Program Files/nodejs/npm:
/mnt/c/Program Files/nodejs/npm: 6: /mnt/c/Program Files/nodejs/npm: Syntax error: word unexpected (expecting "in")

This is due to a pathing issue with a fairly straightforward solution. Using your favorite CLI editor (such as nano, vim, emacs, cat and sed… etc), open your ~/.profile

nano ~/.profile

Note: do NOT attempt to edit Linux files using Windows tools. (Thanks to @david-c-rankin's comment for the official link with the bold red text explaining this) If you don't want to use a CLI editor for this in the terminal, see the bottom of this post for a link on how to get a GUI one running.

Currently, the default bash PATH variable in WSL is

PATH="$HOME/bin:$HOME/.local/bin:$PATH"

Which is injecting the windows path after the first two binary directories. Unfortunately, this doesn't result in /usr/bin being used before the windows installed npm, so add that before the final $PATH:

PATH="$HOME/bin:$HOME/.local/bin:/usr/bin:$PATH"

Save out, and then either reload the terminal or just source the path file

source ~/.profile

Build-essential

If you are using anything which requires compiling or otherwise uses make, it's almost guaranteed that you will need these installed; so if you did not install them while installing node.js, do so. It's much easier to simply use the build-essential package rather than try to install everything separately.

Note that packages such as Compass which rely on Ruby FFI will fail without these. If you are having trouble properly installing and running a tool, making sure you have gcc and make installed can be a good place to start.

sudo apt-get install -y build-essential

Running Tasks using Ubuntu

Note that if you use VS Code's tasks.json to run build tasks, by default it will still run them using the Windows subsystem instead of the Ubuntu one. Sometimes this may be what you want, but if you've just finished installing grunt-cli in Ubuntu and not Windows, it's probably not.

VS Code recently had the 2017 May update to how Tasks work that allows it to set the task runner as the terminal. This is by far the easiest way to migrate tasks over.

Simply set

"runner": "terminal",

in your tasks.json and you're done (assuming you have all of the appropriate tools you are trying to run now installed in WSL Ubuntu).enter image description here

This is very portable, ideally requiring no changes between systems which do or do not have WSL, or to other OSes, and is the method I would recommend.

As of the moment, this method spawns another TERMINAL tab instance (accessed from the drop down). You can still set up appropriate watchers, but it does mean that it's no longer sitting on the OUTPUT tab.

The old method is capable of invoking the WSL Ubunutu Bash shell and having it show up in OUTPUT, and involves either calling bash.exe with the -c argument or using a shell script. It unfortunately is not as semantic, since we are making bash our command and passing it what we want to run as an argument instead. This also means it is not as quickly portable to other systems.

You can use the same location you gave VS Code earlier for the terminal itself, C:\\WINDOWS\\Sysnative\\bash.exe as the value for commandenter image description here

Set the first element of the args array as -c and the second as the command you want to run (credit to the second half of this answer).

Alternatively, you can instead run a shell script as seen here.

Further helpful bits

Want to start VSCode in Windows from the WSL Bash command line?

Want to have a graphical interface for your WSL Ubuntu? (this will allow you to do things like use a Linux GUI editor for files within the Ubuntu system itself: do not edit them using Windows editing tools, see comments/note in section on npm)

Want to build (see the above portion on setting up VS Code Tasks properly for WSL) and debug entirely within WSL Ubuntu? (this shows how to do so using gdb, but the pipeTransport concept could be used with other debuggers) (credit to this answer, but the one before it also provides a method using local loopback that could prove useful)

Solution 2

if you want to use zsh, find path of ubuntu1804.exe or ubuntu1604.exe.

in my case

"terminal.external.windowsExec": "C:\\Users\\asdf\\AppData\\Local\\Microsoft\\WindowsApps\\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\\ubuntu1804.exe",
"terminal.integrated.shell.windows": "C:\\Users\\asdf\\AppData\\Local\\Microsoft\\WindowsApps\\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\\ubuntu1804.exe",

Solution 3

Now you can use Microsoft's WSL extension.

Share:
66,913
taswyn
Author by

taswyn

When I'm not training faculty and staff on our Content Management System, I mostly work on finding ways within an otherwise closed XSLT system to make it friendlier to changes and our needs. You might say that creative work-arounds and hacks are my forte, even. A major passion for me, if not the focus of my work currently, is progressing usability and "user" experience through applied psychological principles and understanding; and I even get to practice that every so often! Outside of work, I'm a mom (of a toddler) with a wide range of hats. No, not the actual hats. More the "hi, someone needs to figure out how to get this done and then do it" type. Things like "ok, we bought it, now how do we put a new vanity in?" or "help, the daughter is getting into things she shouldn't." Wait, that sounds a lot like work, too. I have a background ranging from formal education in computer science to training in fine arts… as well as electronics once upon a time (I still break out the soldering iron now and then and have wanted to find time to do some microcontroller based work)… and even ranging to medieval literature. I help my wife with critiques, advice, and sometimes even direct work with her graphic illustration business, LadyTank Studios, and still dream of some day putting out a video game or two.

Updated on June 06, 2020

Comments

  • taswyn
    taswyn almost 4 years

    While other questions deal with how to use things like git-bash, giving the new WSL a spin as the terminal for VS Code is not the same: it gives you access to bash running on an actual Ubuntu Linux subsystem, instead of the git-bash terminal running on the Windows subsystem.

    So how do we get it working as the VS Code terminal, and particularly how do we get it working as a functional dev environment terminal?

    Unlike git-bash, this is unfortunately not as simple, because the Ubuntu Linux configuration in WSL can provide some gotchas, such as NPM trying (and failing) to run from your Windows Program Files directory due to the interaction between WSL and Windows itself in terms of pathing, and some packages such as Compass failing for what are not necessarily immediately obvious reasons to someone who is not used to developing on Linux. What's a simple way to have a reliable WSL terminal environment for VS Code where most frequently used tools will run when installed via apt-get or npm?

  • David C. Rankin
    David C. Rankin almost 7 years
    Good answer, it is also useful to provide the notice Do not change Linux files using Windows apps and tools to new WSL users. This can come as quite a surprise.
  • taswyn
    taswyn almost 7 years
    @DavidC.Rankin Thanks! I actually thought I had put that in there, around where I advised using a CLI editor for the .profile, but it must have been one of the things I was still looking for a source to link on. I'm going to use your link if you don't mind!
  • Tobias J
    Tobias J over 6 years
    Great writeup, thanks! Not sure if you've seen this, but there is also a registry entry you can make to prevent the Windows PATH from being injected into Bash, which may be easier for many Windows users than manually editing their .profile.
  • taswyn
    taswyn over 6 years
    Hey @TobyJ, thanks for linking that! And no, I wasn't aware of it… I may add it as an option with some caveats, but I think the .profile edit is probably the superior option for most coders, since it carries over any edits you've done to your windows path env variable and allows them to still work for you from the ubuntu side where applicable. I'm not entirely sure that WSL is [currently] a good fit for anyone who would find that edit to be problematic, but I may be biased on that.
  • Chang Qian
    Chang Qian over 6 years
    Great answer that worked out in a flash! But I want to know why setting terminal.integrated.shell.windows to C:\WINDOWS\System32\bash.exe won't work - I used the value "C:\\WINDOWS\\System32\\cmd.exe" before WSL and it's okay, but after changing cmd to bash it only gave me a flashing cursor without prompt. After knowing that Sysnative\bash.exe will do the trick, I tried to browse to C:\\WINDOWS\\Sysnative only to find it does not exist.
  • taswyn
    taswyn over 6 years
    @ChangQian the reason for this is that when 64 bit windows was released, they added a file system redirector for 32 bit programs, because System32 was reserved for 64 bit dlls/software. This results in 32 bit apps that try to access System32 instead accessing SysWOW64 (yes it seems backwards). Sysnative forces this to not happen, but doesn't show up in 64 bit software* like Explorer. You can see an example of this using the 32 bit command prompt: C:\Windows\SysWOW64\cmd.exe and running dir C:\Windows\Sysnative *This works in 64bit VSCode because it's coded to translate it automatically
  • Peterino
    Peterino about 6 years
    Note that git is already installed on recent versions of the Ubuntu App for Windows.
  • Evan Rosica
    Evan Rosica almost 6 years
    @taswyn Can you please post your entire tasks.json file?
  • alxpez
    alxpez almost 6 years
    @taswyn is there any particular reason to install Node.js & NPM on windows instead of doing it directly on the WSL. I'm just wondering about the pros/cons of doing one or the other. BTW, great answer!
  • Bernhard Döbler
    Bernhard Döbler almost 6 years
    When you set your terminal to ubuntu.exe you might end up in you user folder instead of the project's folder. That's why you want to set your terminal to C:\\Windows\\System32\\wsl.exe according to github.com/Microsoft/WSL/issues/2795 Use wslconfig /setdefault Ubuntu to make sure the right installation starts.
  • aderchox
    aderchox over 5 years
    I've taken the steps but the packages I've installed in my wsl previously are not recognized here in the bash inside vscode. Do you know why is that?
  • taswyn
    taswyn over 5 years
    When I wrote this it was when WSL was much more locked down (before the distro choice/etc). I have a machine with a fresh install of windows that's been updated to at least Spring Creator's edition, so I'll finally take a real look shortly at what improvements can be made per various comments and try to answer your question, @Narnia.
  • taswyn
    taswyn over 5 years
    @alpez: sorry if that was confusing (and not getting back to you sooner). What I meant was that if you have Node and/or NPM already installed in Windows (for other uses/dependencies withing Windows) then you need to make SURE that trying to call node/npm from within Ubuntu actually calls the Ubuntu versions (by modifying the PATH env), because the Windows ones won't run correctly from within Ubuntu (WSL). Thus also the need to make sure they're installed in Ubuntu (at the time I wrote this, at least, they weren't pre-installed in WSL) even if you already have them installed in Windows.
  • aderchox
    aderchox over 5 years
    @taswyn thanks! My problem is resolved. I just uninstalled my old version of the ubuntu wsl and now vscode uses the 18.04 as the default one.
  • hamaney
    hamaney over 5 years
    Thanks for your answer. It works as expected unless a virtual environment is involved. When the integrated terminal starts in the project directory, the virenv does not start. The reason is that vscode runs source <WindowsPath>/Scripts/activate instead of /mnt/<WndowsPath>/Scripts/activate. Any suggestions?
  • Salvador P.
    Salvador P. over 5 years
    Worked fine on 1.32 version of visual studio code and WSL with ubuntu. Thanks!
  • airpower44
    airpower44 over 5 years
    @TobyJ github.com/Microsoft/WSL/issues/1493#issuecomment-417639271 With the latest version of WSL the link you previously posted doesn't work.
  • Tobias J
    Tobias J over 5 years
    @airpower44 good catch, thanks, it looks like it was thankfully added to wsl.conf now via appendWindowsPath docs.microsoft.com/en-us/windows/wsl/wsl-config
  • andy
    andy almost 5 years
    it's a good answer but mostly all I needed to know was the path to the new terminal : "C:\WINDOWS\Sysnative\bash.exe" all the other aspects in the answer are left to user's preference. for instance, i want to run node inside my linux bash not install it to windows. And as a small tweak to your PATH section, simply append to .profile export PATH=$PATH:/usr/bin/$PATH and you're golden
  • Michele Piccolini
    Michele Piccolini over 4 years
    For VS Code, I had bash at: "C:\\Windows\\System32\\bash.exe"
  • Zhi Yuan
    Zhi Yuan over 4 years
    its name is: Remote - WSL. Link: marketplace.visualstudio.com/…
  • fireb86
    fireb86 about 3 years
    It works also with ubuntu2004.exe, thank you!
  • Shreyan Mehta
    Shreyan Mehta almost 3 years
    issue : adding wsl in vs code for me the path didnt worked, there is nothing called C:\\WINDOWS\\Sysnative\ in my system. So i first found out wsl which was in C:\\Windows\\System32\\wsl.exe and then somehow i managed to open the config which now correcting wsl looks like "terminal.integrated.profiles.windows": { "PowerShell": { "source": "PowerShell", "icon": "terminal-powershell" }, "wsl": { "path": "C:\\Windows\\System32\\wsl.exe" } } I remvoed other git bash and cmd, since its a bigger json