In my experience, the biggest practical hurdle when running a mix of native and MSYS2 programs is related to tty / pty. I wish I understood perfectly what is going on but at least I think I can explain the problem and what are the options. When I learn more, I'll be happy to update this post.
When you run a shell of your choice like bash.exe
or zsh.exe
, you have three main options:
- Run it in the mintty terminal.
- Run it in Windows console ("cmd.exe").
- Run it via ConEmu connector which is roughly equivalent to starting Command Prompt and running
conemu-msys2-64.exe C:\msys64\usr\bin\bash.exe --login -i
.
mintty is the default in both Git Bash and MSYS2 shells as historically, this used to be a much better experience than using Windows console. The problem with mintty is that it doesn't present itself as a console to native CLI programs which leads to all sorts of issues in practice, for example:
docker run -it ubuntu /bin/bash
will not work, trying to prepend a Windows path before/bin/bash
.npm
andyarn
will not display colorful outputs.python
will refuse to start in interactive mode.gcloud
commands asking for input will seemingly hang.
If you have Node.js installed, you can try this:
# mintty
$ node -p -e "Boolean(process.stdout.isTTY)"
false
# Windows console
$ node -p -e "Boolean(process.stdout.isTTY)"
true
The core issue here is that native Windows programs don't think they are running in an interactive console which leads to all the problems above. You'll observe the same if you run your shell through ConEmu connector.
There are two main options what to do about it:
- Running a shell from Windows console.
- Use winpty.
Windows console ("console host", "conhost") got much better in Windows 10 with colored output, Unicode support, resizable windows, better copy & paste, etc. Microsoft continues to work hard on it so seemingly, avoiding mintty or the connector should be the way to go.
However, after running zsh via Windows console for about a week, I found our that there were too many issues there, for example, colors in my prompt were not working correctly, Yarn and npm were doing some funny path manipulations, @elieux reporeted some issues with mc
and text-based user interface apps in general, etc.
In practice, this was too troublesome.
Winpty provides pty-like interface for Windows programs. Instead of running <some-program>
, you run winpty <some-program>
:
$ node -p -e "Boolean(process.stdout.isTTY)"
false
$ winpty node -p -e "Boolean(process.stdout.isTTY)"
true
❗ Use official winpty binaries, not those from MSYS2, see msys2/MSYS2-packages#411 (comment)
Git for Windows even tries to do this for popular binaries automatically so you can add their code to your .bashrc
/ .zshrc
. Also, for any binaries not in that list, just add the aliases manually, like:
alias npm='winpty npm.cmd'
alias yarn='winpty yarn.cmd'
alias gcloud='winpty gcloud.cmd'
Alternatively, if you don't want to rely on aliases, create a small shell script for each binary like this:
#!/bin/bash
winpty "npm.cmd" "$@"
Now, winpty is not without its issues. They are quite subtle and I didn't encounter anything too serious but if you're interested, VSCode maintains a relatively long list of winpty-related issues in their terminal.
- Git for Windows FAQ, great as always.
- Microsoft/console#57 – issue where Microsoft is gathering feedback on building pty compatibility into Windows Console, and sharing their progress (the issues is WIP as of July 2018).
- Node issue "Node.js doesn't run as tty on windows / cygwin" – some good discussion and explanations.