2

I am working on Linux Ubuntu 16.04.
In this challenge I want to remove some commands from the Linux shell.

Specifically, I want to remove the exit command.
I want that if a user will try to exit the shell with this command, it won't be possible or maybe even send some message instead.

Any idea how can I do it ?
I searched for a file named exit:
find / -name exit

But it found only directories:

/usr/src/linux-headers-4.13.0-41-generic/include/config/have/exit
/usr/src/linux-headers-4.13.0-41-generic/include/config/have/irq/exit
/usr/src/linux-headers-4.13.0-43-generic/include/config/have/exit
/usr/src/linux-headers-4.13.0-43-generic/include/config/have/irq/exit
/usr/src/linux-headers-4.13.0-36-generic/include/config/have/exit
/usr/src/linux-headers-4.13.0-36-generic/include/config/have/irq/exit
/usr/src/linux-headers-4.15.0-43-generic/include/config/have/exit
/usr/src/linux-headers-4.15.0-43-generic/include/config/have/irq/exit

EDIT:
I read here about using trap like this trap "ENTER-COMMAND-HERE" EXIT and I tried trap "sh" EXIT but it still existing the shell.

  • 2
    As far as I know, exit is a builtin (part of the shell itself, not an external application). You'd probably have to modify the source code for the shell in question. Why would you want to do such a thing as preventing a user exiting a shell session, though? (perhaps it would be better to not have exit be an alias for logout in interactive sessions, rather than remove the exit functionality.) – Agi Hammerthief Jan 8 at 10:40
  • 1
    A bit pointless IMHO to remove the exit command, considering that one could send ^D signal, either via keyboard or via printf, or kill the shell process. A challenge though IMHO without a satisfactory solution – Sergiy Kolodyazhnyy Jan 8 at 10:44
  • 1
    There's so many ways to exit a shell session though, so I don't know what purpose disabling exit would serve. – Kusalananda Jan 8 at 11:02
  • While it's an odd request, I don't feel it's overly broad and could be answered (perhaps with diff/patches) if the shell(s) were specified. E235: what shells are you concerned about here? – Jeff Schaller Jan 8 at 17:18
  • @SergiyKolodyazhnyy ^D (VEOF) doesn't send a signal, like ^C (VINTR). It's causing the data already written to the tty to be immediately made available at the other end; if there's no such data, a read at the other end with return 0 (EOF). Also, could you please explain how you could send a ^D to the shell from within the shell with printf? – Uncle Billy Jan 9 at 20:23
12

There is no exit executable, that is one of the shell's (you don't say what shell, so I am assuming bash) builtin commands. As such, the only way to remove it completely is to edit the source code of the shell and recompile it (but look at @Kusalananda's answer for a better approach).

As an alternative, you could add something like this to /etc/bash.bashrc:

alias exit='echo "You can check-out any time you like, but you can never leave!"'

But this is trivially easy to circumvent by anyone who knows even a little bit about *nix.

  • 10
    Welcome to the Hotel Bash ?! – Sergiy Kolodyazhnyy Jan 8 at 10:45
  • Nope, it's 50 Ways to Leave Your Shell – doneal24 Jan 9 at 19:23
  • @DougO'Neal 50 Shades of Bourne ? Sorry, I'm having way too much fun here – Sergiy Kolodyazhnyy Jan 9 at 20:49
12

In addition to what terdon said (basically overriding the special built-in exit command with an alias, or a function for that matter), the bash shell also allows you to disable built-in commands.

To disable the exit built-in command:

enable -n exit

To disallow enabling it again, also disable the enable built-in command:

enable -n enable

Note that, just as with terdon's answer, this only affects the current shell session, unless it is implemented as part of a system-wide shell startup file.

Personally, I almost exclusively use Ctrl+D to exit interactive shell sessions. To circumvent this in bash, set IGNOREEOF to some large integer and make it read-only:

readonly IGNOREEOF=1000

This makes the shell exit after pressing Ctrl+D 1000 times.

You could still kill the shell with e.g. kill -s HUP "$$". You can make the shell ignore the hangup signal with

trap '' HUP

There is no way to prevent the user from forcefully killing the shell with a KILL signal though, but you can remove the built-in kill command as above and install an overriding shell function or alias, but it would still be easy to use /bin/kill:

enable -n kill
kill () { echo 'kill: Operation not permitted' >&2; }

You could also exit the shell through

set -e
false

... unless you disable the set built-in, obviously, but that may be taking it too far, as would trying to prevent exiting by several other less obvious means (some of which, would you want to prevent them, would require modifications to the bash source code).


The issue with

trap 'bash' EXIT

is that it will spawn a new shell when the current shell exits. That new shell is easy to exit though, because it hasn't got the trap set up, unless you install the trap as part of the shell's startup files.

This also does not prevent you from exiting the shell, because strictly speaking, the trap doesn't execute until the shell actually exits. What it gives you is a new shell.

  • The two enable commands probably could be placed into /etc/bash.bashrc or user's personal config file to avoid setting it for each and every shell session. – Sergiy Kolodyazhnyy Jan 9 at 18:24
  • 3
    exec true would also effectively terminate the shell. So would setting some low limits with ulimit, or set TMOUT=1... – Stéphane Chazelas Jan 9 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.