I have the following script:
#!/bin/bash
set -e
function do_it {
rm this-file-does-not-exit
echo "Continuing ..."
echo "Done ..."
return 0
}
if do_it ; then
echo "Success"
else
echo "Error"
fi
echo "End of script"
Which produces:
rm: cannot remove 'this-file-does-not-exit': No such file or directory
Continuing ...
Done ...
Success
End of script
The function is not aborted because running the function in the if
statement disables set -e
for the function (and can not be enabled). This is not what I want.
Running the function outside the if
statement, and collecting the result, is not possible, because in this situation the complete script is aborted if the function fails:
#!/bin/bash
set -e
function do_it {
rm this-file-does-not-exit
echo "Continuing ..."
echo "Done ..."
return 0
}
do_it
if $? ; then
echo "Success"
else
echo "Error"
fi
echo "End of script"
Produces:
rm: cannot remove 'this-file-does-not-exit': No such file or directory
I would like the following:
This can be implemented as follows:
#!/bin/bash
set -e
function do_it {
rm this-file-does-not-exit || return $?
echo "Continuing ..." || return $?
echo "Done ..." || return $?
return 0
}
if do_it ; then
echo "Success"
else
echo "Error"
fi
echo "End of script"
Which produces what I want:
rm: cannot remove 'this-file-does-not-exit': No such file or directory
Error
End of script
But this makes the implementation of the function completely unreadable: each line must be followed with a || return $?
Is there another way of aborting a function, and only the function, whenever an statement in the function fails?
You can use "pipefail" to get the return code of the last executed command in the pipe. I wouldn't say it looks much better than your code, but at least it's shorter.
#!/bin/bash
set -ep
function do_it {
rm this-file-does-not-exit &&
echo "Continuing ..." &&
echo "Done ..."
return $?
}
if do_it ; then
echo "Success"
else
echo "Error"
fi
echo "End of script"
In this case function will stop executing right after first failed command (rm) and the result will be the return code of the last command in the pipeline. If "rm <filename>" will be successful, both echoes should work, and the return code will be 0.
Output:
$ touch this-file-does-not-exit
$ ./script-return.sh
Continuing ...
Done ...
Success
End of script
$ ./script-return.sh
rm: cannot remove 'this-file-does-not-exit': No such file or directory
Error
End of script
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With