Cron shutdown fails to execute

Thanks- Would those be used in the CLI and do they toggle true/false.
Might be useful, do you know where the documentation is?

I didn't see mention of it anywhere, but were you creating the cron job at the user-level? Or is this a system-level cron job?

I tried to take what I believe to be your intended purpose and after a bit of research and different searches, tried to throw together something that might work.

Disclaimer: I am still very actively learning and I don't have much practice creating these kinds of script files and also don't have another machine on which to test the below possible solution. A sanity check on the method might be needed by other, more experienced people here or elsewhere.

I read that if you create a script that adds a user to the /etc/sudoers file and grants permission to execute /sbin/poweroff, you can place it in the /etc/skel/ directory with the execute permission set. This way, the script will be copied to the home directory of any new user and it allows them to execute it for an easy shutdown.

An example script is below that takes one argument, (whoami) which will fill the username variable of the new user's username. That argument is included so that the script works when run while the new user is logged-in and prevents the you, the administrator, from needing to do this process manually for each new user on the machine in question.
It then checks if a sudoers file already exists for that user, and if not, creates one with the necessary configuration to allow the user to run /sbin/poweroff without a password.
You might also notice that it creates a crontab file for a user which calls to shut down the system at the time you specified in your OP, but I believe that the 00 10 indicates a 10:00AM shut down time - I only mention this because you said you wanted the machine to shut down after hours and that they will start up again in the AM. The cron expressions use 24-hour format. That said, you might consider changing to 0 19 for a 7:00PM shut down which is truly after hours. Or even, 59 23 for an 11:59PM shutdown, etc...
Regardless, the file is then given the appropriate permissions. Then, places it in /etc/skel/. It should only allow the user to run the poweroff command without a password. For any other sudo commands, the user will be prompted for the master password.

#!/bin/bash

# Define variables
USERNAME="$(whoami)"
SUDOERS_FILE="/etc/sudoers.d/$USERNAME"
CRONTAB_FILE="/var/spool/cron/crontabs/$USERNAME"
SCRIPT_FILE="/etc/skel/add-sudoers.sh"
BASHRC_FILE="$HOME/.bashrc"

# Check if the sudoers file already exists
if [ -f "$SUDOERS_FILE" ]; then
  exit 0
fi

# Create the sudoers file for the user
echo "$USERNAME ALL=(ALL) NOPASSWD:/sbin/poweroff" > "$SUDOERS_FILE"
chmod 440 "$SUDOERS_FILE"

# Create the crontab file for the user
echo "00 10 * * * /sbin/shutdown -h now" > "$CRONTAB_FILE"
chmod 600 "$CRONTAB_FILE"
chown $USERNAME:$USERNAME "$CRONTAB_FILE"

# Create the script file in /etc/skel/
echo '#!/bin/bash' > "$SCRIPT_FILE"
echo '/sbin/shutdown -h now' >> "$SCRIPT_FILE"
chmod 755 "$SCRIPT_FILE"
chown root:root "$SCRIPT_FILE"

# Add command to .bashrc file
echo "[ -f $SCRIPT_FILE ] && $SCRIPT_FILE \"$USERNAME\" &" >> "$BASHRC_FILE"

# Execute command for current session
[ -f $SCRIPT_FILE ] && $SCRIPT_FILE "$USERNAME" &

Adding a line to the user's .bashrc file allows for automatic execution of the add-sudoers.sh script on login, using [ -f ~/add-sudoers.sh ] && ~/add-sudoers.sh "$USERNAME" &.
On login, the script should be able to run for any user's account, as long as they have permission to create files in the specified directories and modify the crontab and sudoers files for their own user account. The script does not require root or sudo permissions to run, since it only modifies files and settings specific to the user running the script.

You can safely remove the section which creates the script file at /etc/skel/poweroff_script.sh and contains #!/bin/bash\n/sbin/shutdown -h now. The script should still work as intended.

This poweroff_script.sh script file that gets placed in /etc/skel is meant to provide the user with an executable file and provides them an easy way to shut down the machine without needing to type a long command - especially if this script is placed in their home directory or the Zorin menu. However, it is not essential for the user to have this file in order to shut down the machine. The user should still be able to use the shutdown command to initiate a shutdown, which is what the script is already adding to the user's crontab file.

At the very least, this might help you or someone else identify a solution intended to solve your problem if this doesn't work. :bulb:

1 Like

User Level. Worked it out for now.

To my understanding, the only admin function that would be given to each user is the ability to use the shutdown command.

I guess in theory, if the /etc/skel portion is left in there, which copies this script to each user's home directory, they could also be able to find the the script and execute it themselves. The only thing I think would happen then, is that they essentially create the cron entry to activate it and instruct the machine to shutdown at the specified time.

I could be wrong though. We'd have to let someone try it out and report their results.

That does seem like it could work but I don't know how I would make that work as automatically as the other script. The reason I did it that way is because of the requirements to have each user's sudoer file update as well as their cron; both of which I believe need to happen at the user level. This way, the admin account (marcsitkin) wouldn't be required to log in for every user and make their cron and update the sudoer file.

Glad @Marcsitkin was able to get it working or figured out tho.

1 Like

Another avenue a system admin can take:
1- Set up the OS as you normally would.

2a- Set the original installed OS drive to read-only so no one can alter it.

2b- Or install it on an external USB drive that's not plugged into the computer during normal use.

3- Create a .ISO image file of that OS installation.

4- Loop-mount that .ISO file to boot it. It'll have all the necessary drivers and files needed for that computer, and when it's shut down, all the files created since boot-up are gone.

5a- (If you've used 2a above) When you want to update the OS, just set the hard drive where the OS is installed to read/write, do the updates, then go back to #3 above and repeat the process.

5b- (If you've used 2b above) Update the OS installed on the external drive, then go back to #3 above to create a .ISO file, drop that new .ISO file onto the computer's disk to overwrite the existing .ISO file.

Or (if it's having problems with drive lettering):
Install the OS to the computer's drive. Create a .ISO file. Overwrite the installed OS with that .ISO file (drop the .ISO file onto the computer's drive, don't 'burn' it). Loop-mount that .ISO file to boot it. Not sure if that would work, though.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.