Hi all I have a quick question. Is it better for my zsh shell to be in /usr/bin/zsh or /bin/zsh. I remember reading that one of them would mess up the whole system since zsh is not posix compliant. I believe that szh shouldn’t be set as the root shell. I now have it in /usr/bin/zsh, is that good? So now when I drop into a root shell I don’t get they autocompletion feature that zsh has. I’d also lose that fancy theme. Does that mean my root shell is still bash? Thanks
As long as
/bin/sh
isn’t pointing to zsh, you haven’t messed anything up. A lot of public scripts wouldn’t expect to be run under zsh.If you write your own scripts, I’d say to use zsh, but start it with
/bin/zsh
(or whatever resolves to zsh) to be explicit about the fact that it is designed for zsh and nothing else. Most scripts written aren’t going to be distributed to hundred of thousands of systems, but at most used in a handful of systems. No point in not enjoying some things zsh does better in scripts.A lot of systems have other dependencies as well, and as long as a system which has scripts in it is specifing zsh along with other dependencies, I wouldn’t see the problem. zsh doesn’t take up much space or introduce other problems just by being installed.
As for the root shell, you can put
Defaults env_keep += HOME
in your sudo configuration. That will havesudo -s
run your usual zsh with its usual configuration for interactive, daily use. Be aware of any config that shouldn’t be run as root.sudo -i
will still run the shell root is assigned in /etc/passwd, and everything run as root would function ar expected.is better for portability/compatibility. You can set the root shell as whatever you want (including zsh). Leaking the user context with
sudo -s
is generally a bad idea. Unless you actually share a system with multiple users, I’d advise to set a root password and usesu -
in favor ofsudo -i
orsudo -s
. Two (proper) passwords are more secure than one.edit: typo
My collegues wouldn’t appreciate my shell config in the root account, especially the vi bindings ;)
I understand the motivation of using the user environment in the root context. It’s still a bad idea. The assumption is, that it is easier to compromise a non-privileged desktop user than the root account. Imagine some exploit breaking out of a sandbox and doing some minor modifications to your $HOME: either aliasing
ls
to a script somewhere in your home by changing your profile or some shell rc file, or prepending your $PATH environment variable with a folder burried somewhere in your home directory where a scriptls
is placed:#!/usr/bin/env sh if (( $EUID == 0 )); then # do something evil here fi ls "$@"
Now, as an attacker you just wait for some admin on a shared system to come along and use
sudo -s
.
zsh
is supposed to emulatesh
as closely as possible if it is called by that name (it can also beksh
, according to its manual), so I wouldn’t be too concerned even if that did happen.(
bash
can do thesh
trick too. Many(?) distros don’t actually use the bigger shells for that and install something likedash
- a pure POSIX shell with no other bells and whistles - to act assh
when called that way.)Other suspect configurations might not be as fortunate, but this one is fine.
Wherever your distro’s package manager puts it is where it should go. Do not move or mess with the files in /bin or /usr/bin. Their location doesn’t affect anything that you should care about. It is only so the system knows where to find them when working with their packages.
I’m not trying to move any of these two directories, I’m just trying to set the zsh shell as the default and didn’t know which one to choose since there are two.
I recommend you read
man usermod
and particularly the--shell
option for that utilityEdit: also observe how the default shells are stored in
/etc/passwd
(but don’t manually edit that file!)Thank you
Depends on your distro. Various distros are merging /bin into /usr/bin (as you may expect, Debian members have been fighting about this for a while).
In the end it’s all just preferences and conventions. If you want to put zsh in /var/spool/mail/bin/ then you should. As long as you include the path in the necessary
$PATH
variables (and probably make sure ACLs are set alright) it really doesn’t matter for your personal system.POSIX compliance sounds like a weird argument. Any script will have a shebang (
) to pick the interpreter they prefer.
sh
usually meansbash
because of assumptions, but unless you go out of your way, these scripts will not be run throughzsh
.It should be
!/usr/bin/env ...
On my machine
/bin/env
,/usr/bin/env
, and/usr/sbin/env
are all hard-linked to the same file. Probably because every distro puts it some place else and the Manjaro folks just like to be compatible :)On your system. Check out the table halfway down where env is located on different systems: https://www.cyberciti.biz/tips/finding-bash-perl-python-portably-using-env.html
Sure, things usually put env in /usr/bin, but there’s no guarantee for that. All standards like POSIX guarantee is that the standard PATH contains certain binaries.
Hardcoding /usr/bin/env is probably your best bet, but hardcoding any path is making assumptions that POSIX complaint shells don’t guarantee.
That’s why
!env
is probably your best bet, but people hate shebangs without absolute paths.Sure, things usually put env in /usr/bin, but there’s no guarantee for that.
There is even less guarantee for it to be anywhere else.
Hardcoding /usr/bin/env is probably your best bet
Because it is the convention.
That’s why #!env is probably your best bet
It definitely isn’t. That might work in your user space instance of bash in the desktop, but will likely fail in a script invoked during boot, and is guaranteed to fail on several non-gnu/non-linux systems.
!/usr/bin/env
is the agreed convention and there is no probably or but about that. If that does not work on a system it is a bug (looking at you BusyBox containers 🤨).
Thank you for the detailed answer.
Both directories are in your path, and many distros have /usr/bin as a symlink to /bin or vice versa, so it almost certainly doesn’t matter. Also, the location of the shell has no bearing on which shell is used when you log in as root. That’s determined by the login shell field for the root user in /etc/passwd, which is most likely set to bash or /bin/sh (which is most likely a symlink to bash) by default.
/bin
is symlinked to/usr/bin
, so it doesn’t matter.While this is true for most linux distributions, it’s not true for all and there are other POSIX compliant OSs which are not linux at all:
/ # grep -i pretty /etc/*-release /etc/os-release:PRETTY_NAME="Alpine Linux v3.18" / # ls -ld /bin drwxr-xr-x 2 root root 862 Aug 7 13:09 /bin / #
As you can see, /bin is not a symlink there.
Thank you
For the first question, are you using a package manager? If so, I’d say leave it alone. For the second question, your root will likely still be bash unless you changed it yourself.
I use endeavour OS and jump between yay and pacman. I do believe that my root shell is still bash, too, since no trace of zsh is there
In that case leave the files alone for where they’re located.
You could install sudo instead of jumping into a root shell every time you need to do root privileged tasks.
Thank you. I only ever jump into a root shell when I have to. Always use sudo.
Up until now, I’ve only been commenting on other peoples comments to nitpick. I think it is time to give you a comprehensive answer on my own:
You didn’t mention, what distribution you are using. Either way, you should use your distributions package manager to install zsh. Wherever that places the zsh binary is fine; you should not change that! If you want to know where the zsh binary is located, you can issue the command
which zsh
. That zsh should somehow be dangerous as a root shell because it is not POSIX compliant is nonsense. You can use whatever you like as a shell for root. If you don’t want to change the login shell for root, you can just start every shell from any shell by executing it’s binary (i.e. in bash typezsh
, or the other way around). If you want to know what shells on your system are considered viable login shells by your system, you can issue the commandcat /etc/shells
; in your case it should list/usr/bin/zsh
. If you want to change the login shell for a user, as that user runchsh -s ...
where … is the fully qualified path of a valid login shell; to be sure to not make typos or use an alternate path, you can combine that withwhich
, and for example to use zsh use the commandchsh -s $(which zsh)
. If you are the sole user of your system, I’d strongly recommend using seperate configurations for zsh for your normal user and root.So now when I drop into a root shell I don’t get […]
Issuing
su -
orsudo -i
or logging in as root in a full screen TTY (ctrl+alt+F*) will spawn a new shell (the login shell configured for root). If you are unsure, what shell you’re currently in, you can find that out, by issuing the commandreadlink /proc/$$/exe
. Ifreadlink
is not available on your system, you can useps -fp $$
; be aware though, that that will show you the command the shell was started with, not necessarily the path of the shell executable.If you want to write scripts you should always specify the shell it should be executed by with a shebang. For maximum portability/compatibility (do you like to distro hop? want to share it with a friend/the internet?) you should use
env
in the shebang. For you, if you want to script with zsh, that simply means always havingas the first line of scripts.
One may just be a symlink to the other depending on your distro. For shebang lines, I’d probably go with
/bin/zsh
So is the one you’re suggesting not the root one? I’m running endeavourOS. Should I switch it to /bin/zsh?
typically I wouldn’t recommend just moving file paths for packages, especially if you aren’t sure what you’re doing. assuming all you did was
chsh -s
, I wouldn’t worry about it.All I did was chsh -s /usr/bin/zsh
tbh I always go with env variables, usually $SHELL or $zsh are set
I wouldn’t worry about deployment path; there are many reasons not use a fancy shell with root.
In your terminal. ;)