evoldoers / biomake

GNU-Make-like utility for managing builds and complex workflows
BSD 3-Clause "New" or "Revised" License
102 stars 9 forks source link

Observe the SHELL environment variable #54

Open sjackman opened 6 years ago

sjackman commented 6 years ago

Changing the shell to either bash -o pipefail or zsh -o pipefail is useful to catch a failed intermediate stage of a pipe. For example by default cat non-existant-file | gzip >$@ is successful because the gzip is succesful, even though cat failed. Setting -o pipefail causes this pipe to fail correctly.

It's also useful to use zsh to time every command that's run by biomake like so:

export SHELL=zsh -opipefail
export REPORTTIME=1
export TIMEFMT=time user=%U system=%S elapsed=%E cpu=%P memory=%M job=%J

Usually SHELL is used to changed the shell from the default /bin/sh to say zsh -o pipefail, but here's a fun example changing it to python.

SHELL=python

all:
    print("1 + 2 = "); print(1 + 2)
❯❯❯ make
print("1 + 2 = "); print(1 + 2)
1 + 2 = 
3
❯❯❯ biomake
Target all not materialized - build required
print("1 + 2 = "); print(1 + 2)
sh: -c: line 0: syntax error near unexpected token `"1 + 2 = "'
sh: -c: line 0: `print("1 + 2 = "); print(1 + 2)'
While building all: Error 2 executing print("1 + 2 = "); print(1 + 2)
sjackman commented 6 years ago

The default shell used by GNU Make is $SHELL $.SHELLFLAGS where SHELL=/bin/sh and .SHELLFLAGS=-c or .SHELLFLAGS=-ec in POSIX compatibility mode. I prefer -ec myself. See https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html

sjackman commented 6 years ago

I didn't know this:

Unlike most variables, the variable SHELL is never set from the environment. This is because the SHELL environment variable is used to specify your personal choice of shell program for interactive use. It would be very bad for personal choices like this to affect the functioning of makefiles. See Variables from the Environment.

https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html

So SHELL has to be specified in the Makefile.

ihh commented 6 years ago

The Python example would give almost-free SnakeMake compatibility (modulo one parser). This, with a couple other features like provenance, seems noteworthy enough for publication (to me at least), which is a good driver of issue prioritization IMO. So this issue just increased in appeal/priority 👍

sjackman commented 6 years ago

Cool idea! .SHELLFLAGS is useful for other interpreters that use e.g. -e rather than -c. https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html