Unix-like shells on Windows

This post gives some notes on ways to create a Unix-like command line experience on Windows, without using a virtual machine like VMWare or a quasi-virtual machine like Cygwin.

Finding Windows ports of Unix utilities is easy. The harder part is finding a shell that behaves as expected. (Of course “as expected” depends on your expectations!)

There have been many projects to port Unix utilities to Windows, particularly GnuWin32 and Gow. Some of the command shells I’ve tried are:

  • Cmd
  • PowerShell
  • Eshell
  • Bash
  • Clink

I’d recommend the combination of Gow and Clink for most people. If you’re an Emacs power user you might like Eshell.

Cmd

The built-in command line on Windows is cmd. It’s sometimes called the “DOS prompt” though that’s misleading. DOS died two decades ago and the cmd shell has improved quite a bit since then.

cmd has some features you might not expect, such as pushd and popd. However, I don’t believe it has anything analogous to dirs to let you see the directory stack.

PowerShell

PowerShell is a very sophisticated scripting environment, but the interactive shell itself (e.g. command editing functionality) is basically cmd. (I haven’t kept up with PowerShell and that may have changed.) This means that writing a PowerShell script is completely different from writing a batch file, but the experience of navigating the command line is essentially the same as cmd.

Eshell

You can run shells inside Emacs. By default, M-x shell brings up a cmd prompt inside an Emacs buffer. You can also use Emacs’ own shell with the command M-x eshell.

Eshell is a shell implemented in Emacs Lisp. Using Eshell is very similar across platforms. On a fresh Windows machine, with nothing like Gow installed, Eshell provides some of the most common Unix utilities. You can use the which command to see whether you’re using a native executable or Emacs Lisp code. For example, if you type which ls into Eshell, you get the response

    eshell/ls is a compiled Lisp function in `em-ls.el'

The primary benefit of Eshell is that provides integration with Emacs. As the documentation says

Eshell is not a replacement for system shells such as bash or zsh. Use Eshell when you want to move text between Emacs and external processes …

Eshell does not provide some of the command editing features you might expect from bash. But the reason for this is clear: if you’re inside Emacs, you’d want to use the full power of Emacs editing, not the stripped-down editing features of a command line. For example, you cannot use ^foo^bar to replace foo with bar in the previous command. Instead, you could retrieve the previous command and edit it just as you edit any other line inside Emacs.

In bash you can use !^ to recall the first argument of the previous command and !$!$ using $_ instead. Many of the other bash shortcuts that begin with ! work as expected: !foo, !!, !-3, etc. Directory navigation commands like cd -, pushd, and popd work as in bash.

Bash

Gow comes with a bash shell, a Windows command line program that creates a bash-like environment. I haven’t had much experience with it, but it seems to be a faithful bash implementation with few compromises for Windows, for better and for worse. For example, it doesn’t understand backslashes as directory separators.

There are other implementations of bash on Windows, but I either haven’t tried them (e.g. win-bash) or have had bad experience with them (e.g. Cygwin).

Clink

Clink is not a shell per se but an extension to cmd. It adds the functionality of the Gnu readline library to the Windows command line and so you can use all the Emacs-like editing commands that you can with bash: Control-a to move to the beginning of a line, Control-k to delete the rest of a line, etc.

Clink also gives you Windows-like behavior that Windows itself doesn’t provide, such as being able to paste text onto the command line with Control-v.

I’ve heard that Clink will work with PowerShell, but I was not able to make it work.

The command editing and history shortcuts beginning with ! mentioned above all work with Clink, as do substitutions like ^foo^bar.

Conclusion

In my opinion, the combination of Gow and Clink gives a good compromise between a Windows and Unix work environment. And if you’re running Windows, a compromise is probably what you want. Otherwise, simply run a (possibly virtual) Linux machine. Attempts to make Windows too Unix-like run down an uncanny valley where it’s easy to waste a lot of time.

14 thoughts on “Unix-like shells on Windows

  1. Although Mingw is intended as a build environment, with Msys you can get a pretty functional Unix-like environment and is lighter weight than full-up Cygwin.
    I am often confused as to why Cygwin seems to get so little love, though. I wouldn’t say it heavy-weight by 2015 standards, especially so if you only install what you need.
    I have also tried Gow and Gnuwin within the last year or so just to see what they were like and they seemed to only work marginally.

  2. The good news is that cmd is getting a lot of great improvements in Windows 10.

  3. We use Cygwin at work. I’ve used it many times in past, as I want to do command line stuff (sed, grep) on windows. I want to use windows as a) My home computer gets used for games. b) A lot of chemistry software is Windows only and c) Most of my lab doesn’t know *nix, so it would be a problem setting up shared computers at work on it. Yet, bash scripting is really easy and we’d like to use some bits of it for data-processing.

  4. A long-time Cygwin user here. I started using it back in the early Cygnus days to get some UNIX software to build and run under Win95/NT.

    Since then, the Cygwin DLL has provided an amazing level of Linux/BSD/GNU compatibility, always choosing correct functionality over speed (since if you want speed, you won’t use a compatibility layer). Yes, limited or substitute functionality is often provided for new features, but is evolved out over time. Ideal for builds and testing, and occasionally even deployment to Windows.

    I like Windows as a development environment (mainly for deep tool integration with the host OS), but I detest it as a target environment. Cygwin lets me have my cake and eat it too.

    However, when I must do development bouncing between multiple platforms (Windows desktop, Linux x86 servers, Linux embedded ARM via remote X11), my stripped-down IDE of choice is Geany: Runs everywhere, and feels the same.

  5. I second MSYS2. It gives a nice term emulator (mintty), shell (bash) and package manager (pacman). Git for Windows is switching to MSYS2 too.

    Another solution is to use mintty with the old MinGW/MSYS. mingw-get install mintty. Then create a shortcut which runs mintty with a “bash.exe –login -i” from MSYS.

  6. The PSReadline project greatly improves the Powershell terminal experience. It adds features like syntax highlighting, multi-line editing/history, emacs mode, bash-style completion, yank/kill ring, and much more. Highly recommended for anyone spending a lot of time in Powershell.

    As mentioned in an earlier comment, the native console host (which Powershell and cmd live in) is finally getting some love in Windows 10: line-wrapping selection, drag-to-resize with text wrapping, various keyboard shortcuts, and more.

  7. I have better luck with M-x ansi-term than with eshell. It’s got some peculiarities but it strives to be an ANSI-capable terminal. You still have to run bash/whatever inside that so you’ll need cygwin or whatnot.

  8. I believe GOW uses the shell from the winbash project. There are also older versions of tcsh and zsh that have been ported to Windows. Swiss provides a POSIX shell that works on Windows. Also, didn’t notice any mention of Busybox-w32. It provides an ash shell and several utilities in one executable.

  9. A combination that I’ve found useful, which takes up a minuscule amount of space, is:

    * BusyBox (probably best to use the 64-bit version on 64-bit Windows); it gives you a decent shell and over 100 utilities (including Awk):

    * Tiny C Compiler (can generate both 32-bit and 64-bit executables, not highly optimised, but fine for students learning how to program):

    The combination is great for getting students up to speed in a UNIX-like environment without having to install anything major like Cygwin. BusyBox and TCC together can fit on single floppy disk, if anyone remembers those.

Comments are closed.