Long-term archiving + encrypting shell script Yesterday, I very quickly, in an hour, wrote the very first version of my long-term archiving + encrypting shell script.

I am aware it may have too many flaws, but none of them really prevent it from normal operation, so before I take another step and restructure it with printf and better error reporting, structure, exit codes, etc. I would like you to have a look first.

What it does:


It archives a given directory into a tarball.
It compresses (with maximum effort) that tarball using xz.
It encrypts that xz archive using openssl and AES-256.
It creates and checks the created SHA-512 sum file.
It then decrypts the created file to a temporary file.
Finally, it compares the decrypted file with the original xz archive.


I am prepared to waste time and effort in order to be 100% sure before burning my precious data to Blu-ray M-disc.

I know I should not have to do steps 5 and 6 just because there is almost a 0% chance for the data to get corrupted in the process. But since I have a rather large NVMe SSD drive, and relatively fast CPU, it should not be so shocking that I wrote it with motto better safe than sorry.

#!/bin/sh

[ -z "$1" ] &amp;&amp; echo "You need to give me one directory!" &amp;&amp; exit 1

[ ! -d "$1" ] &amp;&amp; echo "This is not a directory!" &amp;&amp; exit 1

[ ! -w "$PWD" ] &amp;&amp; echo "The current directory is not writable by you!" &amp;&amp; exit 1

dir=$(basename "$1")
today=$(date +%Y-%m-%d)

backupdir="${dir}_${today}"
# backupdir="${dir}"

backupfile="${backupdir}.tar"

bold=$(tput bold)
red=$(tput setaf 1)
yellow=$(tput setaf 3)
nocolor=$(tput sgr0)
bold_red="$bold$red"
bold_yellow="$bold$yellow"

echo
echo "${bold_yellow}1/6: TAR is archiving your directory '${bold_red}$dir${bold_yellow}' into '${bold_red}$backupfile${bold_yellow}'${nocolor}"
echo

if ! tar -cf "$backupfile" "$1" --totals
then
    echo "TAR failed to archive your directory"
    exit 1
fi

echo
echo "${bold_yellow}2/6: XZ is compressing your '${bold_red}$backupfile${bold_yellow}' into '${bold_red}$backupfile.xz${bold_yellow}'${nocolor}"
echo

if ! xz --format=xz --check=sha256 -9 --threads=8 --keep --verbose --verbose --extreme "$backupfile"
then
    echo "XZ failed to compress your backup file"
    exit 1
fi

echo
echo "${bold_yellow}3/6: OpenSSL is encrypting your '${bold_red}$backupfile.xz${bold_yellow}' into '${bold_red}$backupfile.xz.enc${bold_yellow}'${nocolor}"
echo

if ! pv -W "$backupfile.xz" | openssl enc -aes-256-cbc -md sha256 -salt -out "$backupfile.xz.enc" -pass file:/home/vlastimil/.blablablabla 2&gt; /dev/null
then
    echo "OpenSSL failed to encrypt your compressed file"
    exit 1
fi

echo
echo "${bold_yellow}4/6: sha512sum is creating hash file '${bold_red}$backupfile.xz.enc.SHA512SUM${bold_yellow}'${nocolor}"
echo

if ! sha512sum -b "$backupfile.xz.enc" &gt; "$backupfile.xz.enc.SHA512SUM"
then
    echo "sha512sum failed to compute hashsum file"
    exit 1
fi

sha512sum -c "$backupfile.xz.enc.SHA512SUM"

echo
echo "${bold_yellow}5/6: Decrypting your '${bold_red}$backupfile.xz.enc${bold_yellow}' into a temporary file '${bold_red}$backupfile.xz.dec${bold_yellow}'${nocolor}"
echo

if ! pv -W "$backupfile.xz.enc" | openssl enc -aes-256-cbc -md sha256 -salt -out "$backupfile.xz.dec" -d -pass file:/home/vlastimil/.blablablabla 2&gt; /dev/null
then
    echo "OpenSSL failed to decrypt your encrypted file"
    exit 1
fi

echo
echo "${bold_yellow}6/6: Comparing your un-encrypted, compressed, archived, directory file '${bold_red}$backupfile.xz${bold_yellow}' with a temporary file '${bold_red}$backupfile.xz.dec${bold_yellow}'${nocolor}"
echo

if ! cmp "$backupfile.xz" "$backupfile.xz.dec"
then
    echo "Failed to compare files"
    exit 1
else
    echo "Your directory '${bold_red}$dir${nocolor}' has been successfully stored as '${bold_red}$backupfile.xz.enc${nocolor}'"
    rm "$backupfile.xz.dec"
    rm "$backupfile.xz"
    rm "$backupfile"
fi
It's a fine script. Even shellcheck doesn't find anything in it. Well done!

I only have minor comments.

You can safely omit the sha512sum -c.
It would only fail if the previous command failed.
For the rest, I cannot say it's complete paranoia.

The password file used with openssl commands is buried in the script and repeated twice.
It would be better to put that value in a variable and define at the top of the file.

A helper function would be more convenient to print the headers for the steps, instead of blocks of echos.


  before I take another step and restructure it with printf and better error reporting, structure, exit codes, etc. I would like you to have a look first


I don't see what benefits printf will bring,
and the error reporting, structure, exit codes look just fine.

I would rename bold_red and bold_yellow to be more about the purpose than presentation.
Like &lt;em&gt; in HTML is for emphasis,
and &lt;strong&gt; for strong emphasis,
And the stylesheet (in this case the actual value of the variables) define the presentation, nicely segregated from the code.