4
\$\begingroup\$

As a continuation of this question, I would like a second review from you.

Here is the updated sh script:

#!/bin/sh
set -e
spath="/home/<user>/<dir>/"
sname="<scriptname>.sh"
if [ $# -eq 0 ]
then
 sh "${spath}${sname}" "logging" 2>&1 | tee -a "${spath}log_$(date +%F_%T_%N).txt"
 exit
fi
cd $spath
# This three commands for logging...
pwd
date
whoami
docker compose down
# To go sure, docker is down and file operations are complete
sleep 5
sudo sh -c "apt update && DEBIAN_FRONTEND=noninteractive apt upgrade -y && apt autoremove -y && apt autoclean"
# To go sure, upgrades are done
sleep 5
if [ -f /var/run/reboot-required ]
then
 # To go sure, system is up again after reboot
 at now + 2 minute -f "${spath}${sname}"
 sudo reboot
else
 docker compose pull
 docker compose build --pull
 docker compose up -d
 # To go sure, docker is running again
 sleep 5
 docker system prune -a -f
 # Just for information/debug logging purposes, everything is up
 sleep 5
 docker system df
 docker stats --no-stream | sort -k 2
fi

The requirements are almost the same. I think it's safer to user sh instead of bash because I use the at command.

asked Oct 7, 2023 at 21:38
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

The base path and the name of the current script

I don't understand the purpose of these lines:

spath="/home/<user>/<dir>/"
sname="<scriptname>.sh"

From the rest of the script I'd guess it's the base path and name of the script. Instead of hardcoding, you could write like this:

spath=$(cd "$(dirname "0ドル")"; pwd)
sname=$(basename "0ドル")

Double-quote variables on the command line

Unquoted variables on the command line are subject to word splitting and globbing by the shell. Most of the time it's not intended, therefore it's better to write cd "$spath" instead of cd $spath.

Even if you know for sure that in this use case $spath will not contain any characters that may lead to word splitting or globbing, it's a good habit to build.

More blank lines please

The script is a "wall of text". Adding blank lines in between sections with tightly related commands would make it easier to read.

Avoid arbitrary sleep

Sleeping for some arbitrary amount of time and hoping that something is ready by the time the sleep ends is error prone. It's better to think of some observable event to wait for.

For example, this code hopes that the container will be down after 5 minutes:

docker compose down
# To go sure, docker is down and file operations are complete
sleep 5

This will fail if sometimes it takes a bit longer, or if you increase the sleep, then sometimes it will be unnecessarily slow. It would be better to sleep 1 in a loop until the container is actually down, and up to some maximum number of iterations.

Hint: use docker-compose ps -q <service_name> to check if the container is down.

Avoid sudo in scripts

After starting a script, I like to assume that I can step away for a coffee and it will be done by the time I'm back. If the script has sudo in the middle, then I might not be there to enter a password.

I recommend to make it mandatory to run the script as root user. That is, when $(id -u) is not 0, print a helpful message and exit 1.

You could add this check after the top part, right before the cd "$spath".

answered Oct 10, 2023 at 18:18
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.