How to Get Exit Status of a Shell Command Used in Gnu Makefile

How to get exit status of a shell command used in GNU Makefile?

In the makefile-:

mycommand || (echo "mycommand failed $$?"; exit 1)

Each line in the makefile action invokes a new shell - the error must be checked in the action line where the command failed.

If mycommand fails the logic branches to the echo statement then exits.

How to get the exit status and the output of a $(shell command) before make 4.2?

I just can't understand why you're trying to make use of $(shell ...) at all. This is so overly complex, and so meaningless. The only effect of $(shell ...) is that it expands before any recipe is run. But you never try to make use of that. On the contrary, it looks only natural to move the script directly inside the recipe.

For example, consider this:

unused = """
ifeq (true,false)
"""

# some python stuff
print("Hello world")
exit(1)

unused = """
endif

# here comes make stuff
.ONESHELL:
.PHONY: all
all:
@/usr/bin/python $(lastword $(MAKEFILE_LIST))
ec=$$?
echo "script exitcode is $$ec"
exit $$ec

#"""

Maybe even better solution is simply to make python a custom SHELL for a single rule. Although, in this case it could be tricky to mix python and shell scripts in the same rule (but I don't think it's really essential).

Gnu make: Run shell command and use exit code to set global variable

If you are interested only in the exit status of your script the easiest is probably to capture it in a make variable and use it in make conditionals or target names. Example with target names:

C_EXIT_STATUS := $(shell ./c.sh &> /dev/null; echo $$?)

.PHONY: all everithing-%

all: everything-$(C_EXIT_STATUS)

everything-0:
@echo "all right"

everything-%:
@echo "not all right ($*)"

And then, if ./c.sh exits with status 0:

$ make all
all right

While if it exits with status 7:

$ make all
not all right (7)

Example with make conditionals:

C_EXIT_STATUS := $(shell ./c.sh &> /dev/null; echo $$?)

.PHONY: all

ifeq ($(C_EXIT_STATUS),0)
all:
@echo "all right"
else
all:
@echo "not all right ($(C_EXIT_STATUS))"
endif

And last but not least, as you suggested yourself, recursive make is also an option:

.PHONY: all

ifeq ($(C_EXIT_STATUS),)
all:
s=0; ./c.sh &> /dev/null || s=$$?; \
$(MAKE) C_EXIT_STATUS=$$s
else ifeq ($(C_EXIT_STATUS),0)
all:
@echo "all right"
else
all:
@echo "not all right ($(C_EXIT_STATUS))"
endif

How do I check the exit status of a Makefile shell invocation?

You can test the returned value on a second command on the same Makefile line, using the shell $? variable that contains the last returned value.

For example with the false command that would obviously stop the compilation:

test:
/bin/false ; /usr/bin/test "$$?" -eq 1 # <-- make does not stop here
/bin/echo "Continues ..."
/bin/false # <-- make stops here

How to check return value from the shell directive

This worked fine for me - based on @eriktous' answer with a minor modification of redirecting stdout as well to skip the output from svn info on a valid svn repo.

SVN_INFO := $(shell svn info . 1>&2 2> /dev/null; echo $$?)
ifneq ($(SVN_INFO),0)
$(error "Not an SVN repo...")
endif

How to make GNU Make fail if a shell command assigned to a variable failed?

In case you are intending to use a call function, and want to abort at one central place (so that future users of GET_SECRET do not forget to check e.g. .SHELLSTATUS), I found this hack practical:

GET_SECRET = $(shell vault read -field=$(1) $(2) || { echo >&2 "Error reading field $(1) from vault path $(2), aborting"; kill $$PPID; })

The parent make process is killed of shell error. See also 225542/how-to-make-a-failing-shell-command-interrupt-make and 50958731/assign-shell-output-to-variable-or-exit-terminate-makefile



Related Topics



Leave a reply



Submit