Handling of shell builtins in make(1)
Harti Brandt
hartmut.brandt at dlr.de
Tue May 24 00:34:54 PDT 2005
On Mon, 23 May 2005, Scott Long wrote:
SL>Harti Brandt wrote:
SL>
SL>>
SL>> Hi all,
SL>>
SL>> I think I found a problem in the shell code in make(1), but I'm not sure
SL>> whether to fix it or not and how. The problem is as follows: in compat mode
SL>> (this is the default mode when make(1) is not called with -j) the command
SL>> lines of a target are executed by one shell per line (this is also how
SL>> Posix wants it). To reduce the number of shells make does an optimisation:
SL>> when the command line does not contain one of a pre-defined set of meta
SL>> characters and does not start with one of a predefined set of shell
SL>> builtins, make directly exec's the command instead of using an intermediate
SL>> shell. The problem is that the current list of builtins is limited to:
SL>>
SL>> alias cd eval exec exit read set ulimit unalias umask unset wait
SL>>
SL>> Obviously this is not the full set of shell builtins and does also not
SL>> contain the shell reserved words.
SL>>
SL>> The result of this is that for one and the same command you can get
SL>> different behaviour whether you execute it via make(1) or via sh -c '...'.
SL>> As an example take echo(1). When called via the sh -c you get the builtin
SL>> echo which supports the -e option, when executed by make(1) you get
SL>> /bin/echo which doesn't. If you suddenly include a shell meta character in
SL>> the command line:
SL>>
SL>> foo:
SL>> echo "MAKEFLAGS: ${MAKEFLAGS}"
SL>>
SL>> you suddenly get also the builtin (':' is a meta character).
SL>>
SL>> For the reserved words the situation is almost the same. With the following
SL>> makefile:
SL>>
SL>> foo:
SL>> if
SL>>
SL>> one gets:
SL>>
SL>> if:No such file or directory, while
SL>>
SL>> foo:
SL>> if [ -x /bin/sh ] ; then echo hey ; fi
SL>>
SL>> you get what you expect.
SL>>
SL>> I think all this may be very confusing. The question is what to do. I see
SL>> the following options:
SL>>
SL>> 1. leave it as it is.
SL>>
SL>> 2. include the Posix reserved words and builtins into the list.
SL>>
SL>> 3. include all reserved words and builtins of our shell into the list.
SL>>
SL>> Option (3) is probably best. With (2) you still get different behaviour for
SL>> the two command lines in:
SL>>
SL>> foo:
SL>> bind -h
SL>> bind -h *
SL>>
SL>> (the first line will try to find bind in the path while the second will
SL>> execute the shell builtin).
SL>>
SL>> Opinions?
SL>>
SL>> harti
SL>
SL>4. Separate /bin/sh into a front end and back end (libsh) and include libsh
SL>into make.
SL>
SL>(running and hiding as I hit the 'send' key)
Would there be other uses for this?
harti
More information about the freebsd-arch
mailing list