5 ms·
Modulinos are nice (using them in Python and Ruby ever since I did Perl), sometimes an entirely self-contained single-sourcefile program is very useful, especia
by lloeki 5y ago
Modulinos are nice (using them in Python and Ruby ever since I did Perl), sometimes an entirely self-contained single-sourcefile program is very useful, especially when leaning on literate programming, yet one may still want its functions to be importable by an outsider program.
Light reminder that this would be a problem when the shell got set -e:
[[ "$BASH_SOURCE" == "$0" ]] && hello
Shellcheck to the rescue, use if; then; fi instead which is barely longer.
- hvdijk 5y agoWhy would that be a problem with set -e? Both in that form and with if-then, if the [[ ... ]] fails, the shell does not exit, if any command in hello (or, in rare cases, hello itself) fails, it does. Shellcheck does not print anything related to this, it only prints "SC2128: Expanding an array without an index only gives the first element."
- lloeki 5y agofoo.sh: set -e function hello() { echo "hello" } [[ "$BASH_SOURCE" == "$0" ]] && hello bar.sh: source foo.sh hello then: $ bash bar.sh; echo $? 1 because the [[ ]] exits with nonzero, right hand of && does not execute, so the whole expression exits with nonzero, and thus the errexit condition triggers, bailing out of everything. This also happens when moving set -e from foo.sh (the modulino, as a lib) to bar.sh (the modulino consumer), so since in the modulino you can't be sure which of +e or -e will be, you basically have to pick the strictest for robustness.
- hvdijk 5y agoThat's not entirely what is happening there. The shell doesn't exit because the [[ "$BASH_SOURCE" == "$0" ]] condition is false. Its status is checked, so it doesn't cause the shell to exit. What's happening instead is that the exit status of the "source" command is that of the last command executed in the sourced file, and its status is not checked, so the failure there does cause the shell to exit under -e. Add a command that's just "true" or ":" or "echo debug" to foo.sh and you'll see a change in behaviour. It's probably best to ensure that sourcing a source-able file results in a 0 return status if sourcing succeeded even under +e, since the caller may be using something along the lines of source file || { echo "failed to source file" >&2; exit 1; }. And sure, using if-then-fi rather than && can be a perfectly good way of achieving that.
- dtgriscom 5y ago[[ "$BASH_SOURCE" == "$0" ]] && hello || true