18

I want to change MSYS2's default shell from bash to zsh.

I've tried chsh - not available in MSYS2.
Editing /etc/passwd does nothing. It seems to be ignored.

I took a look at the batch scripts in MSYS2's root directory, and bash is hardcoded in. I changed every /usr/bin/bash to /usr/bin/zsh, which worked fine, until I tried using MinGW.

Where can I change MSYS2's shell (properly), if at all possible?

9

I just ran into this problem. To get zsh running I did this:

  • Installed MSYS2
  • From the directory I installed MSYS2, I ran mingw32_shell.bat
  • Upgraded all installed packages by running pacman -Syu
  • Installed zsh and curl by running pacman -Sy zsh curl
  • Closed the MinGW shell by running exit - I did not run zsh immediately after installation.
  • Edited msys2_shell.bat, mingw32_shell.bat, and mingw64_shell.bat and changed every instance of: start %WD%mintty -i /msys2.ico /usr/bin/bash --login %* to: start %WD%mintty -i /msys2.ico /usr/bin/zsh --login %* (on line 39 as of 2015-09-23)
  • Ran mingw32_shell.bat
  • At the zsh configuration menu I select 0 to create the .zshrc file.

When configuration finished I saw:

zsh-newuser-install:1119: command not found: rm

Which didn't look right... since rm should never net be found on a healthy *nix system (I'm guessing it's a bug with MSYS2's zsh package), but everything ran fine after that.

The first time I tried this when I ran opened up a batch file to create a new session I received an error about zsh's memory space already being occupied. To fix this I closed all open MinTTY windows and ran the autorebase.bat file in the MSYS2 installation directory. Everything worked after that.

Then I installed oh-my-zsh. Using:

sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

| improve this answer | |
  • I was trying to do basically this method, and I couldn't get fish to work without error. – leetNightshade Apr 12 '18 at 18:17
  • 1
    The rm is actually really innocent. The end of the /usr/share/zsh/functions/Newuser/zsh-newuser-install script contains an rm -f $tmpfile* to clean up after itself. It's exactly the same in my Fedora install's current /usr/share/zsh/5.7.1/functions/zsh-newuser-install. – FeRD Jul 4 '19 at 18:42
27

I ran into this using the newer msys2-launcher, that provides .exe launchers rather than batch files.

For this, it was simply a matter of changing the .ini files alongside the launchers inside the Msys2 root directory (for a 64-bit installation, it might contain msys2.ini, mingw32.ini and mingw64.ini). For each of those ini files, add a line to set the shell:

SHELL=/usr/bin/zsh
| improve this answer | |
  • This is the direct way to set zsh as the shell. For setting up oh-my-zsh one might consider this method - the skel part does not really apply to msys2 as far as I see. – TNT Mar 7 '18 at 13:04
  • 2
    This is the correct answer for newer msys2 as of July 2018. The accepted answer no longer works. – GaryO Jul 24 '18 at 14:01
  • 2
    not working anymore (14/03/19) – letroll Mar 14 '19 at 8:45
6

Edit /etc/nsswitch.conf, and change the setting below:

db_shell: /bin/zsh
| improve this answer | |
  • This works but seems a rather hackish version of Alan Pearce's solution. – TNT Mar 7 '18 at 13:07
  • I couldn't get this to work trying to use fish. – leetNightshade Apr 12 '18 at 18:18
  • I found this answer here too: github.com/elieux/msys2-launcher/issues/… but Alan Pearce's answer seems nicer. Both works though, and you can also set the shell inside the msys2_shell.cmd bat file, but changing it in the .cmd file doesn't affect the shell if you have to start from one of the .exes – Jose V Jan 8 at 13:44
4

When changing default shell is not supported, one way to use the shell you like is to start it immediately when the default shell starts.

For example, just write zsh to ~/.bashrc, and when bash starts, it will run zsh for you. How ever a stray bash process is left running, and you have to quit shell twice when logging out. To make it better, write exec zsh instead of zsh, this way, the bash process is completely replaced with a zsh process.

This method is not perfect but it should work well in most cases. Compared to changing hard-coded values, it may cause less compatibility issues.

It is first mentioned in this answer on StackOverflow.

| improve this answer | |
  • Nothing nice or fancy about this, but it works with the least fuss. – leetNightshade Apr 12 '18 at 18:18
3

My install did not have the files mentioned in the accepted answer (msys2_shell.bat, mingw32_shell.bat, and mingw64_shell.bat).

Instead my Win10 system install of MSYS2 (using the installer file msys2-x86_64-20161025.exe) has a single file, msys2_shell.cmd with the line:

set "LOGINSHELL=bash"

I changed bash to zsh. Seems to work so far.

| improve this answer | |
  • your solution not worked for me on Win7 have you do other things after that? – letroll Mar 20 '19 at 8:45
  • 1
    Sorry, I don’t have any further information. I moved on to WSL, which works for my needs. Good luck. – xtian Mar 20 '19 at 11:36
  • this worked for me on win10 – Jose V Jan 7 at 9:09
  • however if you need to start msys2 from one of the .exe files then this won't set the shell, for that look into Alan Pearce's answer – Jose V Jan 8 at 13:45
1

I've got a solution but it requires that you use ConEmu instead of whatever other terminal you're currently using. Give it a try though, in my opinion, it's the best terminal app on windows.

First of all, you'll need to install zsh using pacman. I guess you've gotten that far already. Then, you'll need to install ConEmu (which you can do with Chocolatey or just by downloading the installer from the conemu site). In the ConEmu settings, under 'Tasks', you should add a new task. It probably already has one called Bash::Msys2-64 or something like that so maybe you'll make one called Zsh::Msys2-64. The name is arbitrary in any case. In the 'Commands' box for this new task, you can basically copy the command from Bash::Msys2-64 and substitute zsh.exe where appropriate. Mine is like:

set CHERE_INVOKING=1 & %ConEmuDrive%\msys64\usr\bin\zsh.exe --login -i -new_console:C:"%ConEmuDrive%\msys64\msys2.ico"

Then, in ConEmu's 'Startup' options, you can set this as your startup task so that opening ConEmu gets you right into your Zsh every time. Obviously you can also set a key combo for opening it or any other task in a new tab or whatever you want. ConEmu has loads of options so I'm sure you'll be able to set it up however you like.

| improve this answer | |
0

The MSYS2 devs obviously keep changing their setup, because in the newest installs, the msys2_shell command that's installed in Windows to launch the MSYS2 environment(s) accepts a -shell argument.

So, to use a different shell, you can edit the Properties of one or more of the launchers for MSYS2 / MinGW 32 / MinGW 64, and update the Target to add -shell zsh or whatever. (If the shell is in $PATH for the MSYS environment that's sufficient, you don't need the full path.)

So, for e.g. the "MSYS2 MinGW 64-bit" launcher in "MSYS2 64bit" on my Win7 Start menu:

Before
Target: C:\msys64\msys2_shell.cmd -mingw64
After
Target: C:\msys64\msys2_shell.cmd -mingw64 -shell zsh

That seems to be the easiest and most compatible way to switch permanently, since your changes won't get wiped out by upgrades or whatever.

Oddly enough the launchers doesn't respect any environment variables, registry entries, etc. Unless -shell is passed on the command line to override it, the LOGINSHELL=bash default that it initially forces will be used.

| improve this answer | |
  • 1
    I start mingw64 directly, so mingw64.ini is the way to go, setting the SHELL parameter to /usr/bin/zsh. And that has been working for year IIRC (I just deactivated it for a while when the zsh was broken in msys2 as a login shell) – Jürgen A. Erhard May 23 at 9:55
0

EDIT: The below is applicable to earlier versions of MSYS2. As of 2020-01-21, it is not required any longer. FeRD's answer seems to work best.

I wanted to use fish instead of bash. Unfortunately most of the methods here didn't work, possibly because fish syntax is so different.

What worked best was wzhd's idea about running exec fish as the first thing when bash begins. There was still a problem, however: If I wanted to use bash, I had to edit .bashrc to remove that line because even if I run it from fish it would just start another fish instance.

The best thing to do is to make sure that exec fish runs when msys2 begins, but not every time bash begins.

The way I found is through the file msys2_shell.cmd in msys2's installation folder. I found these lines:

set SHELL_ARGS=

:collectparams

if not "x%~1" == "x" set SHELL_ARGS=%SHELL_ARGS% %1& shift& goto :collectparams

It seems they're defining parameters to pass to bash as soon as it begins, but only when this script runs (unlike .bashrc). So I added this line just after:

set SHELL_ARGS=%SHELL_ARGS% -c "exec fish"

Everything seems to be fine so far. Starting msys2 replaces bash with fish as soon as the former finishes loading, but if I need a bash command line I can still just start it with bash.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.