Change default shell from bash to zsh by default?


zsh seems to have much better usability, a much better completion features and other features. See demonstration here:

Looks great:


2 Packages, ~ 5 MB.


  • breaking bash scripts: each script nowadays has a shebang in its first line such as for example /usr/sbin/apparmor-info is a bash script, its first line is #!/bin/bash. Therefore the script will still run under bash, not zsh.
  • changing back default shell to bash by the user will still be simple
  • it will be trivial to start bash from zsh by typing command bash
1 Like

I say go for it…

That said, I still use bash for my default shell because I have built all my dotfile config over the years to use bash. but I should just rip the bandaid off and embrace the zsh light

1 Like

Made zshrc and some others misc scripts to be portable to any shell (.aliasrc, .shrc are posix compliant).

Please download the following packages:

sudo apt install zsh zsh-syntax-highlighting zsh-autosuggestions

Copy the dot files to the home dir.

If you want the developer prompt, uncomment it whonix-shell/.zshrc at b835e3eeac83cbbb4eca2bd3c845a7aa497dccea · nyxnor/whonix-shell · GitHub
basically it shorts the path if too large and also show git branch

and whonix-shell/.zshrc at b835e3eeac83cbbb4eca2bd3c845a7aa497dccea · nyxnor/whonix-shell · GitHub
uncomment the RPS1 if you want it to print the exit code of failed commands on the right side.

Tell me what you think, what should be changed, bugs etc.

1 Like

Unicode needs to be removed.
(Detecting Malicious Unicode in Source Code and Pull Requests)
(Not saying it’s malicious but currently the easiest is to permit no unicode at all in scripts as per project policy.)

grep -P -n '[^\x00-\x7F]' -r --color .zshrc

It’s just the … sign.

Maybe it could be encoded somehow (such as <b> becoming bold in html) to have a similar optical effect?

Other than above minor comments… Excellent! Excited to see this being added to Whonix. The command completion is just on steroids. Easier than reading man pages. Makes less common command line parameters much more accessible.

Showing the exit code seems highly useful. Instead of telling users in documentation to append ; echo $? to commands or echo $?… What do you think about always showing the exit code? If zero, a (0). Probably in a green color. Other colors for other numbers.

However, showing the exit code in the terminal could have some unintended side effects? Such as… When the user copy/pasted the log, the reader (other forums etc.) might be confused?

This is the effect it has:

[workstation user …ault.service.d/test/test/test]%

I am gonne replace it for three normal dots ...:

[workstation user ...lt.service.d/test/test/test]%

It eats two characters more, but that is not a problem.

It is 1 character containing 3 small dots, I don’t know how to do that without unicode, but 3 normal dots in 3 characters is still fine.

1 Like

The unix way is to be silent when the exit code is 0, and I think that if there is an exit code worth checking is the one that is >0, because than the brain is just warned to look at the exit code if an error ocurrs.

I found this but it only works to print on the line before and not on the prompt.

setopt PRINT_EXIT_VALUE seems to be the better to print the line before:

[workstation user ~/git/whonix-shell(main)]% zsh
[workstation user ~/git/whonix-shell(main)]% a
zsh: command not found: a
zsh: exit 127   a
[workstation user ~/git/whonix-shell(main)]%

but still doesn’t print exit code 0 because it is not relevant?

not with setopt PRINT_EXIT_VAUE example from above, it already has the text zsh: exit 127 command.
It may take oneline more on errors but may be better?

1 Like
1 Like

Please feel free to proceed with integrating this by default in Kicksecure / Whonix.

Ideally using ZDOTDIR environment variable if possible. “Stealing” (overwriting) config files from Debian’s zsh (or any other) package using config-package-dev should be avoided if somehow possible.


Looks really nice.

Yeah, I guess so. No strong opinion here.

I am looking at this from a different perspective. More like: I always want to see some result even if it means “OK” because otherwise I question if the mechanism to show the error itself is broken. Maybe very likely unlikely here. These fail-safe considerations of mine are probably less important than the usability impact of only showing exit codes on failure.

Or to find out about unexpected exit codes. (Zero when it should be non-zero.)

If nobody else has an opinion here, probably best to only show the non-zero exit codes by default.

Looks really great.

Where should ZDOTDIR be set? Which file will export that variable?

Change for that? Remove RPS1 in favor of the setopt PRINT_EXIT_VALUE?

1 Like


/etc/X11/Xsession.d + /etc/profile.d
Similar to other examples in Whonix source code.
…unless there are other solutions that I am not aware of. Distributions setting global environment variables is messy. There are probably no better solutions.

Seems to be dependent on Xorg being installed

Zsh does not source that folder unless in compatibility mode, which is not what we want.

I am still searching for other directories…

1 Like

Yes but it’s OK to drop config file snippets in that folder independent of Xorg being installed. So that doesn’t speak against using it. If a drop-in is there, then Xorg is supported.

So seems setting that environment variable in Xorg is easy and reliably possible thanks to /etc/X11/Xsession.d.

For Virtual Consoles I am not sure. I will probably open a separate forum thread because setting environment variables might need a re-design if possible.


Maybe I found a solution…

  • No need to use /etc/X11/Xsession.d.
  • No need to use /etc/profile.d.
  • Only use /usr/lib/systemd/system.conf.d mechanism.



Reboot required.

dist stands for distribution. What distribution? Kicksecure and Whonix. I couldn’t come up with a better common name. That’s where the “dist” is coming from. Kept it open so potentially other distributions could fork it so neither Kicksecure nor Whonix are inside the package or folder name if not required.

Does this work? What do you think?

What is the reason it can’t be in Skel?

Systemd does not work on Qubes apparently per your mentioned post.

.zprofile symlink to .config/shell/profile

.config/shell/profile exports ZDOTDIR="${XDG_CONFIG_HOME:-$HOME/.config}/zsh"

ZDOTDIR contains the .zshrc

I think this is the cleanest way. The only thing is that skel needs to have some files. Is there a problem in that?

It does not depend on external program being installed and used.

Oops. Forgot to write DefaultEnvironment=. Now fixed and edited in above post.

Could you try again please?

I tested it with other variable names. Maybe it only works for other variable names and unfortunately there is some mechanism breaking it for ZDOTDIR.

[Imprint] [Privacy Policy] [Cookie Policy] [Terms of Use] [E-Sign Consent] [DMCA] [Contributors] [Investors] [Priority Support] [Professional Support]