this post was submitted on 15 Aug 2023
41 points (100.0% liked)

Linux

45530 readers
1083 users here now

From Wikipedia, the free encyclopedia

Linux is a family of open source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991 by Linus Torvalds. Linux is typically packaged in a Linux distribution (or distro for short).

Distributions include the Linux kernel and supporting system software and libraries, many of which are provided by the GNU Project. Many Linux distributions use the word "Linux" in their name, but the Free Software Foundation uses the name GNU/Linux to emphasize the importance of GNU software, causing some controversy.

Rules

Related Communities

Community icon by Alpár-Etele Méder, licensed under CC BY 3.0

founded 5 years ago
MODERATORS
 

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

top 32 comments
sorted by: hot top controversial new old
[–] [email protected] 19 points 10 months ago (2 children)

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 have sudo -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.

[–] [email protected] 9 points 10 months ago* (last edited 10 months ago) (1 children)

#!/usr/bin/env zsh 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 use su - in favor of sudo -i or sudo -s. Two (proper) passwords are more secure than one.

edit: typo

[–] [email protected] 3 points 10 months ago (1 children)

My collegues wouldn't appreciate my shell config in the root account, especially the vi bindings ;)

[–] [email protected] 4 points 10 months ago* (last edited 10 months ago)

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 script ls 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.

[–] [email protected] 6 points 10 months ago

zsh is supposed to emulate sh as closely as possible if it is called by that name (it can also be ksh, according to its manual), so I wouldn't be too concerned even if that did happen.

(bash can do the sh trick too. Many(?) distros don't actually use the bigger shells for that and install something like dash - a pure POSIX shell with no other bells and whistles - to act as sh when called that way.)

Other suspect configurations might not be as fortunate, but this one is fine.

[–] [email protected] 16 points 10 months ago (1 children)

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.

[–] [email protected] 2 points 10 months ago (1 children)

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.

[–] [email protected] 1 points 10 months ago* (last edited 10 months ago) (1 children)

I recommend you read man usermod and particularly the --shell option for that utility

Edit: also observe how the default shells are stored in /etc/passwd (but don't manually edit that file!)

[–] [email protected] 1 points 10 months ago
[–] [email protected] 15 points 10 months ago (2 children)

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 (#!/bin/env sh) to pick the interpreter they prefer. sh usually means bash because of assumptions, but unless you go out of your way, these scripts will not be run through zsh.

[–] [email protected] 3 points 10 months ago (1 children)

It should be #!/usr/bin/env ...

[–] [email protected] 1 points 10 months ago (1 children)

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

[–] [email protected] 1 points 10 months ago (1 children)

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

[–] [email protected] 1 points 10 months ago (1 children)

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.

[–] [email protected] 1 points 10 months ago

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/envis 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 🤨).

[–] [email protected] 2 points 10 months ago

Thank you for the detailed answer.

[–] [email protected] 7 points 10 months ago

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.

[–] [email protected] 5 points 10 months ago (1 children)

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.

[–] [email protected] 1 points 10 months ago (1 children)

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

[–] [email protected] 1 points 10 months ago (1 children)

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.

[–] [email protected] 1 points 10 months ago

Thank you. I only ever jump into a root shell when I have to. Always use sudo.

[–] [email protected] 5 points 10 months ago (2 children)

/bin is symlinked to /usr/bin, so it doesn't matter.

[–] [email protected] 4 points 10 months ago

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.

[–] [email protected] 1 points 10 months ago
[–] [email protected] 4 points 10 months ago

I wouldn’t worry about deployment path; there are many reasons not use a fancy shell with root.

[–] [email protected] 4 points 10 months ago

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 type zsh, 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 command cat /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 run chsh -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 with which, and for example to use zsh use the command chsh -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 - or sudo -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 command readlink /proc/$$/exe. If readlink is not available on your system, you can use ps -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 having #!/usr/bin/env zsh as the first line of scripts.

[–] [email protected] 4 points 10 months ago (2 children)

One may just be a symlink to the other depending on your distro. For shebang lines, I'd probably go with /bin/zsh

[–] [email protected] 1 points 10 months ago (1 children)

So is the one you're suggesting not the root one? I'm running endeavourOS. Should I switch it to /bin/zsh?

[–] [email protected] 1 points 10 months ago (1 children)

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.

[–] [email protected] 1 points 10 months ago* (last edited 10 months ago)

All I did was chsh -s /usr/bin/zsh

[–] [email protected] 1 points 10 months ago

tbh I always go with env variables, usually $SHELL or $zsh are set

[–] [email protected] 1 points 10 months ago

In your terminal. ;)