In my bash script I redirected stdout and stderr to a logs file to prevent it from being printed in the terminal.
I set my script to exit on error occurrence using set -e
switch.
Now, whenever any part of the code fails (exits with a non-zero exit code) the script stops being executed (as intended), but the trap part does not print my custom error message.
Additionally, when script stops execution, it doesn’t print a new line, resulting in the prompt staying in the same line as the last thing that was echoed by the bash script.
Bash script:
#!/usr/bin/env bash
###############################
# env variables
###############################
#Environmental variables - paths to files storing installation logs and dependencies names to be installed
readonly LOGS_DIRECTORY="./logs/cherry-install/"
readonly LOGS_FILE=""$LOGS_DIRECTORY""$(date +%d-%m-%y_%H-%M-%S)".txt"
readonly ZYPPER_PACKAGES="./dependencies/zypper_packages.txt"
readonly ZYPPER_PATTERNS="./dependencies/zypper_patterns.txt"
###############################
# non-installation functions
###############################
#Create logs directory
mkdir -p "$LOGS_DIRECTORY"
#Redirect stdout and stderr to logs file
exec 3>&1 1>>"$LOGS_FILE" 2>&1
echo() (
>&3 command echo "$@"
)
#Force script to exit on ERR occurence
set -e
#Error handler to call on ERR occurence and print an error message
error_handler(){
echo -e " An error occured! See the installation logs file for specific information.n"
}
trap 'error_handler' ERR
trap "echo -e 'nInstallation terminated manually!'; exit" SIGINT
#Universal function to read dependenies names from a file
read_file(){
packages=()
while IFS= read -r line || [[ -n "$line" ]]; do
packages+=("$line")
done < "$1"
}
###############################
# installation functions
###############################
#Zypper repos refresh and package installation
install_zypper_packages(){
read_file "$ZYPPER_PACKAGES"
echo -n "[i] Refreshing zypper repositories: "
zypper -n refresh
echo 'OK'
for line in "${packages[@]}"; do
clean_line="${line//[^[:alnum:]-]/}"
echo -n "[i] Installing "$clean_line": "
zypper -n install -t package "$clean_line"
echo 'OK'
done
echo ""
}
install_zypper_packages
Output when non-zero exit code is returned (script stops, but no trap message is printed).
lenovo:/scripts/Cherry-VM-Manager/environment-setup # ./cherry-install.sh
[i] Refreshing zypper repositories: OK
[i] Installing docker: OK
[i] Installing egvnjuiq: lenovo:/scripts/Cherry-VM-Manager/environment-setup #
3