I use a Makefile (with GNU make running under Linux) to automate my grunt work when refactoring a Python script. The script creates an output file, and I want to make sure that the output file remains unchanged in face of my refactorings.
However, I found no way to get the status code of a command to affect a subsequent shell if command.
The following rule illustrates the problem:
check-cond-codes:
diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$$!=
diff -q poalim report2008_4.csv; echo differences: =$$!=
The first 'diff' compares two equal files, and the second one compares two different files. The output is:
diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$!=
no differences: ==
diff -q poalim report2008_4.csv; echo differences: =$!=
Files poalim and report2008_4.csv differ
differences: ==
So obviously '$$!' is the wrong variable to capture the status code of 'diff'. Even using SHELL := /bin/bash at beginning of the Makefile did not solve the problem.
A variable returning the value, which I need, would (if it exists at all) be used in an 'if' command in the real rule.
The alternative of creating a small ad-hoc shell script in lieu of writing all commands inline in the Makefile is undesirable, but I'll use it as a last resort.
Related:
If you are passing the result code to an
if
, you could simply do:Use '$$?' instead of '$$!' (thanks to 4th answer of Exit Shell Script Based on Process Exit Code)
Try `\$?' I think the $$ is being interpreted by the makefile
The bash variable is
$?
, but why do you want to print out the status code anyway?Don't forget that each of your commands is being run in separate subshells.
That's why you quite often see something like:
And when debugging, don't forget the every helpful -n option which will print the commands but not execute them and the -p option which will show you the complete make environment including where the various bits and pieces have been set.
HTH
cheers,
I think you're looking for the
$?
shell variable, which gives the exit code of the previous command. For example:To use this in your makefile, you would have to escape the
$
, as in$$?
:Do note that each command in your rule body in make is run in a separate subshell. For example, the following will not work:
Because the
diff
and theif
commands are executed in different shell processes. If you want to use the output status from the command, you must do so in the context of the same shell, as in my previous example.