Issue
I have a simple bash script:
#!/bin/bash
# Zip data and upload it to a cloud storage provider
set -euo pipefail
# some config and funcs removed, only relevant are left.
file=foo
dest=bar
temp_dir=$(mktemp -d)
fail() {
log "$1"
exit 1
}
log() {
echo "$(date) - $1"
echo "$1" | systemd-cat -p notice -t cloud_archive
}
put_archive() {
# Put archives into storage.
# This is where we fail
cp "${file}" "${dest}" || fail "Uploading failed"
}
cleanup() {
# remove some temp files etc.
# and send message to stdout and journal
log "Deleting temp dir ${temp_dir}."
rm -r "${temp_dir}"
}
put_archive
trap cleanup EXIT
From my understanding this is the basic use case for a bash trap. The cp
command fails with $? != 0
, triggering the fail
function, which in turn sends a log message to the journal and then exit 1
. The trap
should catch that signal and fire cleanup
. That part is what does not work. The script just exits with log message "Uploading failed" and does not fire cleanup
. I do not see the log output from that function and temp_dir
still exists.
What I did:
- Remove
set -euo pipefail
- Add
set -x
to verify executed commands, which did not result in anything useful - There are no subshells which might interfere with the
trap
trap
is not used within a function which could have been not yet defined when the script exits
I am having a hard time understanding what I am doing wrong. What am I not seeing here?
Solution
Just place trap
directive line before running your put_archive
function!!
Otherwise, if your function fail
, your fail
function will exit your script before executing trap directive.
fail() {
log "$1"
exit 1
}
put_archive() {
something || || fail "some message"
}
trap cleanup EXIT
put_archive
But you could build another exit way:
fail() {
log "$1"
cleanup 1
}
log() {
echo "$(date) - $1"
echo "$1" | systemd-cat -p notice -t cloud_archive
}
cleanup() {
log "Deleting temp dir ${temp_dir}."
rm -r "${temp_dir}"
exit ${1:-0}
}
put_archive() {
cp "${file}" "${dest}" ||
fail "Uploading failed"
}
put_archive
cleanup
Doing so, you don't need to use trap
directive.
Answered By - F. Hauri - Give Up GitHub Answer Checked By - Timothy Miller (WPSolving Admin)