I've been trying different things without success
so here is what I want to achieve
set -o pipefail
dump "$@" "$db" | compress | store "single" "$(backupName "$db")"
# I would want something that behaves a bit like this
# meaning if it dump fails, don't store
dump "$@" "$db" && {
#migicGetStdout | compress | store "single" "$(backupName "$db")"
} || {
echo failed
}
But it creates a empty file on failed dump
I'm lost with pipeline
I've tried things like
set -e
set -o pipefail
dump "${dumpCommonArgs[@]}" "${dumpDbArgs[@]}" "$@" "$db" > >(compress | store "single" "$(backupName "$db")")
# or
( compress | store "single" "$(backupName "$db")" ) < <(dump "$@" "$db") || return 2
# or
## this way compress get the global $@ ... I don't understand that either
store "single" "$(backupName "$db")" < <(dump "${dumpCommonArgs[@]}" "${dumpDbArgs[@]}" "$@" "$db") > >(compress)
# there would be an easy one
dataToStore=$(dump "$@" "$db")
rc=$?
# but this means dump is stored in memory before saving... not the best deal as mysql already needs a lot of ram to run a dump
store
function is still called!
So seems I'm missing something.
Thanks for helping me out
CodePudding user response:
You'll have to store the output of dump
temporarily; example with a variable:
if out=$(dump "$@" "$db")
then
printf '%s\n' "$out" |
compress |
store "single" "$(backupName "$db")"
else
echo failed 1>&2
exit 1
fi
or test for the emptiness of stdout (is there's no output when it fails):
dump "$@" "$db" | {
IFS='' read -r line
[ -n "${line: _}" ] || { echo failed 1>&2; exit 1; }
{ printf '%s\n' "$line"; cat; } |
compress |
store "single" "$(backupName "$db")"
}
CodePudding user response:
based on @Fravadona answer I end up writing a more generic function and thought it would be nice to share it too.
could be saved as a on-empty-return
in /usr/local/bin
not forget sudo chmod x /usr/local/bin/on-empty-return
then could be used anywhere :)
#!/usr/bin/env bash
set -u
set -o pipefail
##
# usage
# echo "" | on-empty-return 2 cat > /tmp/should-not-create-file || {
# >&2 echo "test failed, file is untouched (status $?)";
# }
#
# outputs to stderr
# Error: stdin is empty. (on-empty-return)
# test failed, file untouched not touched (status 2)
#
# cmd1 | on-empty-return 2 cmd2 args
# to output direct to file use cat
# cmd1 | on-empty-return 2 cat > 'file'
#
# if cmd1 output is empty, cmd2 won't be executed and will return code 2
# otherwise it'll return status code of cmd2 (assuming we have 'set -o pipefail')
#
# arg1: returned status on empty - optional default: 1
onEmptyReturn() {
local emptyRc=1
local re='^[0-9] $'
[[ ${1-} =~ $re ]] && { emptyRc=$1; shift; }
IFS='' read -r line
[ -n "${line: _}" ] || { >&2 echo "Error: stdin is empty. ($(basename $0))"; return $emptyRc; }
{ printf '%s\n' "$line"; cat; } | "$@"
return $?
}
onEmptyReturn "$@"
exit $?
Snippet on GitLab