0

Consider the following Bash alias:

alias su='sudo -s'

The problem one might encounter is running it (that alias) while already root.

Demo:

$ su
[sudo] password for vlastimil:                
# su
# su
# 
exit
# 
exit
# 
exit
$ 

Is there a way to avoid the nested shell sessions?

Important note: I am using the same alias file for my user and root, not separate.

2 Answers 2

3

su and sudo -s are different commands with different APIs and semantic and behaviour, you shouldn't alias one to the other.

Here it seems you want a command that starts root's login shell as root via sudo but only when invoked from a non-privileged shell, so I would write a script called rootshell for instance as:

#! /bin/sh -

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}

[ "$#" -eq 0 ] || die "Usage: $0

Starts a root shell, no argument accepted."

[ "$(id -u)" -eq 0 ] && die "You're already superuser!"

exec sudo -s

Or if you don't want to make a script, make it a shell function by wrapping that code as rootshell() (<that-code>) to add in your shell rc file (change $0 to the name of the function as not all shells put the function name in $0).

2
  • I can always do \su if I want, so what's the point? Nov 20, 2022 at 9:17
  • 2
    @VlastimilBurián That's similar to saying "I called my command that recursively finds PDF file ls. I can always do \ls if I just want to list files". The point is that you have two very different commands and you're calling one by the name of another.
    – Kusalananda
    Nov 20, 2022 at 10:14
0

My solution follows:

alias su='[ $(id -u) -ne 0 ] && sudo -s'

  • POSIX compatible, which means if you copy-paste it to dash or I suppose almost any other shell supporting aliases, you should get the same behavior.

  • That is also why I avoided EUID and direct value comparison altogether.


Demo:

$ su
[sudo] password for vlastimil:                
# su
# su
# su
# 
exit
$ 

Considering I use sudo -s, I attach its comparison with sudo -s vs other variants.

5
  • Wouldn't it be simpler to do alias su=: for the root user? You have to define the alias for the root user anyway, so might as well alias it to a no-op directly since you already know it's for root
    – muru
    Nov 20, 2022 at 6:22
  • @muru I forgot to say in the question something important. But you are correct in your way! Nov 20, 2022 at 6:46
  • Ah, but my point still stands - instead of doing the check at runtime, do the check at definition time: if [ $(id -u) -eq 0 ]; then alias su=: ; else alias su='sudo -s'; fi
    – muru
    Nov 20, 2022 at 7:00
  • @muru Very good! I missed it :) Nov 20, 2022 at 7:08
  • 1
    aliases are for csh users. Bourne-like shells have functions which are much more appropriate if you want to create a new command without having to write a script. aliases are just text replaced with other text before shell syntax interpretation. So here, some-cmd || su -c other-cmd for instance won't do what you want because that's expanded to some-cmd || [ $(id -u) -ne 0 ] && sudo -s -c other-cmd. Nov 20, 2022 at 10:45

You must log in to answer this question.

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