Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rm -f fails for missing files when using "bash -e" as shell in GNU Make 4

I have a Makefile that looks as follows:

.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS = -e

clean:
    rm -f foo

.PHONY: clean

foo doesn't exist. When I run this on Debian, GNU Make 4.1 I get this error:

rm -f foo
/bin/bash: rm -f foo: No such file or directory
Makefile:6: recipe for target 'clean' failed
make: *** [clean] Error 1

When I run it on macOS, GNU Make 3.81 it works as expected. It makes no difference if I write -rm -f instead of rm -f.

Why do I get the error? Running bash -e -c "rm -f foo" ; echo $? in a shell prints 0 on both systems.

Am I missing something?

like image 580
Johan Levin Avatar asked Oct 21 '25 15:10

Johan Levin


2 Answers

The error message has to be read quite carefully:

/bin/bash: rm -f foo: No such file or directory

This isn't a message from rm saying it can't find foo, it's a message from Bash telling it can't find the file rm -f foo (with the spaces in the filename).

With .SHELLFLAGS = -e, the shell gets what would equal the command line:

bash -e "rm -f foo"

So it looks for a file rm -f foo to read commands from. You need to explicitly add the -c flag to tell it to take the argument itself as a command, i.e. .SHELLFLAGS = -ec, resulting in

bash -ec "rm -f foo"

Not surprisingly, the default value for .SHELLFLAGS contains -c:

The argument(s) passed to the shell are taken from the variable .SHELLFLAGS. The default value of .SHELLFLAGS is -c normally, or -ec in POSIX-conforming mode.

like image 176
ilkkachu Avatar answered Oct 23 '25 05:10

ilkkachu


That is an invalid setting for .SHELLFLAGS. It will result in this being invoked:

/bin/sh -e 'rm -f foo'

which is not a valid command line; it's telling the shell to run a program named, literally, rm -f foo which is obviously wrong. You have to be sure you add the -c option as well, and since many shells only allow options in the first argument, you'll need:

.SHELLFLAGS = -ec

This is documented in the GNU make manual.

The reason it "works" in the older GNU make 3.81 is that this version doesn't support the .SHELLFLAGS option at all, so that line is just ignored.

like image 45
MadScientist Avatar answered Oct 23 '25 06:10

MadScientist