1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<h1 class="section">The shell Function</h1> <p>The <code>shell</code> function is unlike any other function other than the <code>wildcard</code> function (see <a href="wildcard-function">The Function <code>wildcard</code></a>) in that it communicates with the world outside of <code>make</code>. </p> <p>The <code>shell</code> function provides for <code>make</code> the same facility that backquotes (‘<samp>`</samp>’) provide in most shells: it does <em>command expansion</em>. This means that it takes as an argument a shell command and expands to the output of the command. The only processing <code>make</code> does on the result is to convert each newline (or carriage-return / newline pair) to a single space. If there is a trailing (carriage-return and) newline it will simply be removed. </p> <p>The commands run by calls to the <code>shell</code> function are run when the function calls are expanded (see <a href="reading-makefiles">How <code>make</code> Reads a Makefile</a>). Because this function involves spawning a new shell, you should carefully consider the performance implications of using the <code>shell</code> function within recursively expanded variables vs. simply expanded variables (see <a href="flavors">The Two Flavors of Variables</a>). </p> <p>An alternative to the <code>shell</code> function is the ‘<samp>!=</samp>’ assignment operator; it provides a similar behavior but has subtle differences (see <a href="setting">Setting Variables</a>). The ‘<samp>!=</samp>’ assignment operator is included in newer POSIX standards. </p> <p>After the <code>shell</code> function or ‘<samp>!=</samp>’ assignment operator is used, its exit status is placed in the <code>.SHELLSTATUS</code> variable. </p> <p>Here are some examples of the use of the <code>shell</code> function: </p> <div class="example"> <pre class="example">contents := $(shell cat foo)
</pre>
</div> <p>sets <code>contents</code> to the contents of the file <samp>foo</samp>, with a space (rather than a newline) separating each line. </p> <div class="example"> <pre class="example">files := $(shell echo *.c)
</pre>
</div> <p>sets <code>files</code> to the expansion of ‘<samp>*.c</samp>’. Unless <code>make</code> is using a very strange shell, this has the same result as ‘<samp>$(wildcard *.c)</samp>’ (as long as at least one ‘<samp>.c</samp>’ file exists). </p> <p>All variables that are marked as <code>export</code> will also be passed to the shell started by the <code>shell</code> function. It is possible to create a variable expansion loop: consider this <samp>makefile</samp>: </p> <div class="example"> <pre class="example">export HI = $(shell echo hi)
all: ; @echo $$HI
</pre>
</div> <p>When <code>make</code> wants to run the recipe it must add the variable <var>HI</var> to the environment; to do so it must be expanded. The value of this variable requires an invocation of the <code>shell</code> function, and to invoke it we must create its environment. Since <var>HI</var> is exported, we need to expand it to create its environment. And so on. In this obscure case <code>make</code> will use the value of the variable from the environment provided to <code>make</code>, or else the empty string if there was none, rather than looping or issuing an error. This is often what you want; for example: </p> <div class="example"> <pre class="example">export PATH = $(shell echo /usr/local/bin:$$PATH)
</pre>
</div> <p>However, it would be simpler and more efficient to use a simply-expanded variable here (‘<samp>:=</samp>’) in the first place. </p><div class="_attribution">
<p class="_attribution-p">
Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc. <br>Licensed under the GNU Free Documentation License.<br>
<a href="https://www.gnu.org/software/make/manual/html_node/Shell-Function.html" class="_attribution-link">https://www.gnu.org/software/make/manual/html_node/Shell-Function.html</a>
</p>
</div>
|