Fix Windows broken SSH console output

Overview

If you're developing sites using a VM on Windows, you're no doubt having to SSH into the box to accomplish various tasks; I do this with Laravel's Homestead.

Unfortunately, the experience on Windows (as opposed to Mac) seems to be completely broken with 2 show-stopping issues:

  1. Seemingly random characters
  2. Garbled / overwritten output

Problem

In the vanilla Windows console, pretty much as soon as you start typing within the SSH session, you're seeing chains of random characters eating your input and making it impossible to do anything meaningful:

These are "control codes", sent by the UNIX VM to display colors, or inserted as you hit keys like delete or cursor left, right, etc.

Even worse, when editing text files using something like Nano, typing or navigation overwrites content. Page up and page down can completely destroy what's on screen:

overwriting

This comes down (apparently) to the fact that cmd.exe is a console, not a terminal (and doesn't emulate one either).

Either way, it makes getting anything done impossible at best, and downright dangerous at worst – but fortunately it is solvable.

The solution comes in 2 parts:

  1. Install a terminal emulator to fix control codes and display colors
  2. Use a different SSH client to Windows' own to fix overwriting

Fix control codes: Install a terminal emulator

There are lots of these around, but the two I've got best results from seem to be ConEmu and Cmdr (which uses ConEmu behind the scenes).

Get one of these installed (I've been using ComEmu the most) and then set Windows to use ConEmu by default, by opening Settings > Integration > Default terminal and clicking the "Force ConEmu as default terminal for console applications":

conemu settings

As a bonus, both emulators support multiple tabs, attractive colour schemes, shortcut keys, and have multiple other usability features.

Not sure how to make PHPStorm use ConEmu yet, but it would be really useful.

Fix overwriting: Use a different SSH client

The overwriting issue seems to be caused entirely by Windows' own SSH client.

Connecting to the VM with anything other than this solves the problem. I've now connected with both PuTTY and Git's OpenSSH and they both work.

However, if you're using Laravel and Homestead, it seems to bypass any changes you make to your default SSH client (even when changing the PATH) so you will now need to log in manually, rather than just typing homestead ssh (but the results are worth it).

Option 1: PuTTY

Using the instructions here (and here), you can run up an SSH session each time you want to connect. Use the following settings:

  • Host: 127.0.0.1
  • Port: 2222

When prompted:

  • Username: vagrant
  • Password: vagrant

You will then be logged in.

Option 2: OpenSSH

Using this method, you can save the code as a shortcut.

Save the following code as a .bat file, making sure the path to OpenSSH is correct (I'm using the one that came with Git):

cd C:\Program Files (x86)\Git\bin
ssh vagrant@127.0.0.1 -p 2222

The first time you run it, right click on the file and select "run as administrator" to add the host to the list of known hosts.

When the console pops up enter the password "vagrant" and you're in.

Option 3: Launch OpenSSH sessions directly within ConEmu

You can set up a ConEmu task to start a problem-free OpenSSH session automatically.

  1. Open ConEmu's settings
  2. Go to Startup > Tasks
  3. Create a new task using the + button
  4. Name your task "Vagrant"
  5. Paste the above code in the "Commands" box
  6. Save your settings

conemu-settings-run

You can then pop open an SSH session from ConEmu by going to the "Create new console" dropdown and selecting your task there:

conemu-run

 Summing up

I've been using Windows console to SSH into VMs for about a year now, and it's been awful. This is especially galling as the experience on the Mac is just so much better.

However, if I need to quickly jump into a project and I'm not using OSX, this is the way to do it.

What a relief!

 

Comments are closed.