I would like to customize the shell for a Makefile, but I am running into trouble. Here is a MWE. I have a Makefile,
SHELL=./my_shell.sh
all: abc def
abc:
touch abc
def:
touch def
clean:
rm -f abc def
and a simple custom script, my_shell.sh
.
#!/bin/bash
eval $*
I made sure to run chmod +x my_shell.sh
beforehand. Then, when I typed make
, I got an error.
make[3]: Entering directory `<CONFIDENTIAL>'
touch abc
./my_shell.sh: line 2: eval: -c: invalid option
eval: usage: eval [arg ...]
make[3]: *** [abc] Error 2
make[3]: Leaving directory `<CONFIDENTIAL>`
I have been struggling to get rid of the -c
option. Setting .SHELLFLAGS=''
doesn't seem to work.
First, if you want to set a make variable to empty use
.SHELLFLAGS =
By adding the quotes you've actually set the variable to the literal string ''
(make is not the shell and does not do shell quote stripping).
Second, the .SHELLFLAGS
variable was added in GNU make 3.82 so if your version is older than that, it won't work. If you have 3.82 or newer then it does work (I just tried it).
Lastly, as Jean-François points out you will problems if your command has escaped spaces. However, his solution of using "$@"
cannot work as-is, because then the entire command is seen as a single string.
A more reliable implementation of the script would be:
#!/bin/bash
exec /bin/bash "$@"
And then do not modify .SHELLFLAGS
. Or else, do set .SHELLFLAGS
to empty and make your script:
#!/bin/bash
exec /bin/bash -c "$@"
SHELL
expects a shell command like bash
or csh
. make
invokes the shell command using -c
as first argument (command option).
Since you pass all arguments directly to the eval
commands you get that error.
Use shift
to skip the first -c
argument that you are not using.
#!/bin/bash
shift
eval $*
And maybe you'll need "$@"
instead of $*
if the arguments have spaces.