I doubt that this is safe now, just because it's so easy for code that won't work with those flags turned on to get written by accident in the absence of these flags.
What do you mean by "I doubt that this is safe now"? Do you mean that Automake will probably generate standard recipes which break if I turn those flags on? Or do you only mean that it is easy for me to write unsafe code in my own makefile recipes?
So as far as Automake-generated rules are concerned, I'd expect "errexit" to be generally safe to enable.
That is a first step. I would also guess that enabling "pipefail" should be similarly unproblematic. The problems are probably nounset and .ONESHELL, right? I think that .ONESHELL is global, isn't it? Otherwise, I would mark only my own recipes with .ONESHELL, and Automake-generated recipes wouldn't be impacted.
However, "make this safe and turn it on by default when the shell supports it" seems like a desirable goal, and one I'd support for both Automake and Autoconf. [...]
I do not think that this goal is worth pursuing. Scripts which do not check for errors are defective in my opinion. If I do not set those flags globally, I have to set them in every recipe, and that is only really practicable with .ONESHELL if the rules have several lines. At the moment, I write Makefile.am recipes like this: $(FILENAME_WITH_SORTED_LIST): set -o errexit && set -o nounset && set -o pipefail && \ echo "Generating the list of filenames passed to the linker..." && \ printf '%s\n' $(OBJECTS_USED_FOR_LINKING) >"$(FILENAME_WITH_UNSORTED_LIST)" && \ .. But that is a pain, as you can easily forget "&& \" at the end of a line. I was hoping to avoid that in the future. If I do not set those flags globally, or in every recipe, then I have to manually check whether each pipe redirection has failed, and I cannot really check whether all used shell variables have been defined. My code does not have to be that portable, Bash is available all over the place, and reasonable shells should have supported those flags since many years now, much earlier than POSIX Issue 8. I would rather lose some portability than write brittle scripts and effectively say "if the shell does not support it, then silently ignore any eventual errors". I would add an option to Automake to simply require those "modern" flags and generate the shell code accordingly. But that is a lot of work, I do not know anything about the Automake internals myself, and such an endeavour probably wouldn't have enough traction. Incidentally, I would guess that supporting .ONESHELL would make the generated makefiles much faster. Or does Automake already generate standard recipes in one single, possible very long, shell line?
The biggest problem with these options is that they are portability nightmares: the behaviour of "set -e / set -o errexit" is quite inconsistent between different shells (not to mention full of surprising gotchas if shell functions are used),
What you say about errexit is true, but unfortunately, there is no other practicable way. Without errexit, you are bound to miss too many possible errors. A code generator may be able to generate code to check every possible error, but when writing shell scripts manually, that is unfeasible. It would make the code too long and hard to maintain. I personally use (and require) pipefail etc., lint with ShellCheck, and recommend using Bash. That is the most you can achieve in practice. It is not completely water tight, but is actually rather close. And it is portable enough nowadays. Please copy me on any answers, as I am not subscribed to this mailing list. Regards, rdiez
