25

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?

1

10 Answers 10

8

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.

1
  • 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) May 23, 2020 at 9:55
34

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
5
  • 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, 2018 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, 2018 at 14:01
  • 4
    not working anymore (14/03/19)
    – letroll
    Mar 14, 2019 at 8:45
  • This works for me using fish as of version 3.3.5-341.x86_64 (July 2022). Though Fish does sometimes spam "kill: not enough arguments". Based on internal discussion, this may be fixed in 3.5, which is not available for MSYS2 yet. Jul 8, 2022 at 16:39
  • 1
    @letroll I figured out why this isn't working. This only works if you start MSYS directly. In other words, through msys2.exe and not msys2_shell.cmd. The start menu entries all run msys2_shell.cmd behind the scenes. For those who don't use the wrapper script this is the best way to go.
    – midrare
    Oct 6, 2022 at 20:20
10

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)"

2
  • I was trying to do basically this method, and I couldn't get fish to work without error. Apr 12, 2018 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, 2019 at 18:42
7

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

db_shell: /bin/zsh
3
  • This works but seems a rather hackish version of Alan Pearce's solution.
    – TNT
    Mar 7, 2018 at 13:07
  • I couldn't get this to work trying to use fish. Apr 12, 2018 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, 2020 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.

1
  • Nothing nice or fancy about this, but it works with the least fuss. Apr 12, 2018 at 18:18
4

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.

4
  • your solution not worked for me on Win7 have you do other things after that?
    – letroll
    Mar 20, 2019 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, 2019 at 11:36
  • this worked for me on win10
    – Jose V
    Jan 7, 2020 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, 2020 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.

1

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.

0

Extending the answer by @FeRD:

I like to run the seven MSYS2 environment terminals inside Windows Terminal. Here's an example Command Prompt command to start one of the MSYS2 terminals:

C:/msys64/msys2_shell.cmd -defterm -here -no-start -ucrt64 -shell bash"

The -ucrt64 part says to launch the UCRT64 environment. The -shell bash part says to use the Bash shell. Other options include -shell fish or -shell zsh, for example. See here: https://www.msys2.org/docs/terminals/.

From my MSYS2 setup answer here: Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal:

Note that if you want to use another shell, such as fish or zsh, you can use -shell fish or -shell zsh instead of -shell bash in the [command] above. See here: https://www.msys2.org/docs/terminals/. If you aren't sure, stick with -shell bash.

All 7 MSYS2 environment options are as follows, also from my main answer:

  1. msys and msys2 (same thing now) - the base MSYS2 tool; all other environments below inherit from this one; contains the GCC 64-bit compiler and Cygwin C library
  2. mingw32 - Minimalist GNU for Windows 32-bit; contains GCC 32-bit compiler
  3. mingw64 - Minimalist GNU for Windows 64-bit; contains GCC 64-bit compiler
  4. ucrt64 - UCRT (Universal C Runtime) 64-bit; contains GCC 64-bit compiler; MSYS2 says: "If you are unsure, go with UCRT64 [this one]." Works by default only on Windows 10 or later.
  5. clang64 - contains the LLVM/Clang 64-bit compiler
  6. clang32 - contains the LLVM/Clang 32-bit compiler
  7. clangarm64 - contains the LLVM/Clang 64-bit ARM (AArch64) compiler

Note that the C:/msys64/msys2_shell.cmd --help menu doesn't show all of those options. That's a bug. But, if you open the C:/msys64/msys2_shell.cmd batch file in a text editor, you'll see it parses all 7 of those options. Read more about that in my main answer too.

0

Take MSYS MinGW-w64 as an example. Starting it by msys2_shell.cmd -mingw64 -shell zsh generally works. If you run msys2_shell.cmd -help or dive into the :printhelp section of msys2_shell.cmd, you can see that the option -shell SHELL sets the login shell, i.e., the LOGINSHELL variable of msys2_shell.cmd. msys2_shell.cmd sets it to bash at first by default; if -shell option is given, i.e., "x%~1" == "x-shell" (also "x%~2" == "x" is false, i.e., SHELL is not empty), LOGINSHELL is set to SHELL (i.e., "x%~2"). After setting this, at the startup of mingw64, it starts zsh.

However, this fails for one case where your HOME environment variable is changed to some other directory, e.g., D:\ProgramData\SPB_Data. At the startup of mingw64, it starts zsh but cannot find .zshrc because ~/.zshrc is probably somewhere else. It will prompt you to exit or manually create it. If you choose to create it, you can find it located under D:\ProgramData\SPB_Data, and its content is merely something like "# Created by newuser for 5.9".

You can for sure copy a complete .zshrc to that place, but for this question, just find your /etc/bash.bashrc file and add

exec zsh

in the end. This solution given by @wzhd provides the most compatibility.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .