[Solved *]substitute reboot for shutdown

* The only portion of this that is not solved is having webmin provide user feedback that the shutdown command was NOT executed. Will try to remember to update if a reasonable solution is found.
Greetings all.

I am looking for guidance on the best way to prevent the shutdown command from being executed. It would be best if a blurb comes up on the session that says “You IDIOT, how are you going to get the system to start back up? Use REBOOT instead!” As you probably guessed already, the system is remotely located and there is no practical way to restore operation after shutdown but power interruption. I can’t do that easily…

The warning isn’t imperative and as far as I can see, sudo doesn’t change anything. If I need to ssh into this system it is because I am doing system level admin changes. Shutdown is the one command that I am most likely to use that would be relatively unrecoverable. Others like network config changes aren’t at all likely. Needing an occasional reboot is very likely and a shutdown issued in haste instead of reboot just makes things worse@!

Also, if I am using Webmin, I would like the same response. Either “NO” or simply substitute reboot and move on.

Thanks for your thoughts.

Q

Easiest is to override the shutdown command with a local shell script (and make it executable):

echo '#!/bin/sh
echo "You IDIOT, how are you going to get the system to start back up? Use REBOOT instead!"' > /usr/local/sbin/shutdown
chmod +x /usr/local/sbin/shutdown

Or even give it some warning color:

echo '#!/bin/sh
echo -e "\e[31mYou IDIOT, how are you going to get the system to start back up? Use REBOOT instead! \e[0m"' > /usr/local/sbin/shutdown

A bid background info about that:

  • When calling a command from terminal, without giving any explizite path to it’s binary, it is searched within the directories given by the $PATH variable. By default it does and should look like this, possibly with some appendix from software installs, which invoke their own binary directories:
2019-02-07 19:53:34 root@micha:/tmp# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  • The binary is searched from the first to the last included paths, so in my case (default) /usr/local/sbin has highest priority and the matching binary there will be used, even that it exists as well in /sbin.
  • You can check, which binary is used by running: which shutdown
2019-02-08 19:27:06 root@micha:/tmp# which shutdown
/sbin/shutdown
  • After adding the replacing script to /usr/local/sbin, it then looks like this:
2019-02-08 19:45:29 root@micha:/tmp# echo '#!/bin/sh
echo "\e[31mYou IDIOT, how are you going to get the system to start back up? Use REBOOT instead! \e[0m"' > /usr/local/sbin/shutdown
2019-02-08 19:45:37 root@micha:/tmp# chmod +x /usr/local/sbin/shutdown
2019-02-08 19:45:42 root@micha:/tmp# which shutdown
/usr/local/sbin/shutdown
  • You can check all matching binaries in all $PATH directories and ordered by priority via: which -a shutdown
2019-02-08 19:33:49 root@micha:/tmp# which -a shutdown
/usr/local/sbin/shutdown
/sbin/shutdown
  • Now calling shutdown results in a fancy red:
2019-02-08 19:35:00 root@micha:/tmp# shutdown
You IDIOT, how are you going to get the system to start back up? Use REBOOT instead!

Thanks MichaIng,

Your detailed response was invaluable in clarifying the best approach to handling the issue and very much appreciated! There is only one ‘little’ part left to do to [s o l v e] this completely - see end of post.

I ended up using:

echo -e "ARE YOU LOCAL TO THE MACHINE? \e[1;31mHow are you going to restart the system? \e[0mIf you really want to shutdown use the full path (/sbin/shutdown).  Otherwise use reboot. "

Note the extra -e at the beginning. I put this in the “/usr/local/sbin” along with another essentially identical file named “poweroff” which is what webmin executes.

I found the website https://misc.flogisoft.com/bash/tip_colors_and_formatting very helpful in tuning what ends up on screen.

In an effort to extend the method to webmin, I put a identical file named “poweroff” in that folder as well as that is what it is using. Then added “/usr/local/sbin” to webmin > webmin configuration > operating system and environment program search path.

The only part that still doesn’t work is that webmin does not put the echo output up on it’s user interface page. All that happens when you click to initiate is -well- nothing apparently. I am sure the script executes but of course you never get a message that says why a shutdown didn’t happen. Almost a separate issue it would seem. Does anyone have any guidance for this part? I do believe that I have seen ‘stuff’ come back on screen from other ?similar? situations but the devil is in the details!


Q

quanta
Ah jep forgot about the “-e” to translate the color code in the inner echo :roll_eyes:, will add it above for other users visiting this topic.

To not double the script code (and the need to change both, if wanted), use a symlink: ln -sf /usr/local/sbin/shutdown /usr/local/sbin/poweroff

Webmin indeed is another topic. Never used it and are not sure about what is printed in it’s web UI under what conditions and if it successfully translates color codes e.g.
I am just trying it out. You mean when you select: System > Bootup and Shutdown > Shutdown System (at the bottom)?
The output of this is pretty sure based on internal code and has nothing to do with the script, nor can its content change anything about that.

I tried to forward the output to the STDERR (1>&2) stream and giving the script explizite failure state (exit 1), but Webmin does not check any of those. It obviously simply calls the command and does nothing else about it’s output/result, expecting the system to shutdown.

Thanks again, MichaIng.

I suspected symlink would be an option. I am not a practiced linux user so most of the time it is simpler for me to use the brute force and possibly more direct method. Most of what I do doesn’t need to scale. My order of priority is (do stuff) then (learn stuff). It may seem backwards but if you think about it and don’t over emphasize one over the other, it seems to be a reasonable approach.

… STDERR… I understand what you are getting at. I know that with some commands you get back a response. I think I have seen this when starting and stopping some system services but not certain which. You do get back “done” for some and sometimes I have seen an error (other than indications that a service or module is not configured or installed etc.) I have posed the question on a webmin forum so should I give this a slightly qualified (s o l v e d?).

Q

As long as there are not further questions, please. At least there is nothing more we can do about it our side :wink:.


Saturday night taking some time to share knowledge and care user support requests :sunglasses: :slight_smile::

  • When running commands/scripts on Linux there are two standard output streams, STDOUT and STDERR: https://en.wikipedia.org/wiki/Standard_streams
  • STDOUT is for standard output messages for user information and such.
  • STDERR is for error messages.
  • But it’s up to the binary/script which stream it uses for which output, so it might be not used 100% consistent. E.g. if you see [FAILED] … from DietPi programs, these are actually printed to STDOUT even that they are actually sort of error messages.
  • You can grab and forward those streams, STDOUT with the “1” and STDERR with “2” and forward them with “>” to a file or even into another stream:
2019-02-09 21:29:24 root@micha:/tmp# echo test # echo uses STDOUT
test
2019-02-09 21:29:57 root@micha:/tmp# echo test 1> /dev/null # Forward STDOUT to /dev/null file to suppress terminal output
2019-02-09 21:30:04 root@micha:/tmp# this produces an error 1> /dev/null # Causing an error will print to STDERR
bash: this: command not found
2019-02-09 21:30:33 root@micha:/tmp# this produces an error 2> /dev/null # Forward STDERR to /dev/null file to suppress terminal output
2019-02-09 21:39:21 root@micha:/tmp# this produces an error 2> /dev/null 2>&1 # Forward STDERR to /dev/null but forward it as well into STDOUT stream, so it is still shown
bash: this: command not found
  • And besides that there is an exit code that can be catched with the $? variable, where 0 means no error and any other integers means an error, usually:
2019-02-09 21:34:05 root@micha:/tmp# echo test; echo $?
test
0
2019-02-09 21:34:18 root@micha:/tmp# this produces an error; echo $?
bash: this: command not found
127

So theoretically it would have been possible for webmin to track either the exit code or STDERR output and show it in the web UI in case, so the user knows if somehow the poweroff command failed. But yeah… if this command fails, then usually there are much larger issues present on the system :wink:.