I've got a Makefile that runs a tool that takes a little while; it allows me to replace the command used:

make TOOL=alternative-tool

I'd like to skip that step in the Makefile, so I'm looking for a command that exits with status 0, and that has negligible side-effects.

Obviously, I could just use true, but that's kinda confusing:

make TOOL=true

That reads as if I want to run the tool, but I don't.

Is there a default-installed executable that isn't /bin/true that exits with status 0, and that has a catchy and easy to type name?

  • Makefiles support comments, gnu.org/software/make/manual/html_node/Makefile-Contents.html . Put a comment before the line and document your code. That reduces confusion and explains why you used a certain approach. – Freiheit Apr 20 '18 at 18:33
  • 1
    What line? The TOOL=true will be on the command line when invoking make, probably documented in a README nearby. The actual line that invokes the tool is somewhere within a 7000-line (third party) makefile. – Roger Lipscombe Apr 20 '18 at 18:45

Even though you've asked for something that is "not /bin/true", replacing true with the full name /bin/true to show that it is the true program rather than some other meaning of "true" is probably the best solution.

Your concern is that the true in

make TOOL=true

appears to be something other than a command name. But if you write

make TOOL=/bin/true

then that is unambiguously a command. Somebody might misread TOOL=true to mean that some other tool somewhere is intended, but no such misreading of TOOL=/bin/true is likely.

I am unsure as to when :, which is a shell builtin but not an external command, will work. Henning Makholm has reported that it appears to work. But I think it does not work in all situations, and you found that it did not work for you.

As for a shell alias, you cannot use that because alias expansion is not performed in the arguments you pass to a command, nor do makefiles make any use of previously defined shell aliases. Even if make runs your commands in a new shell, that shell will not have the alias (and would not use it even if it did have it, because it would be a noninteractive shell, where alias expansion is not automatically enabled).

  • 1
    Using : seems to work fine for me. make always spawns a shell to run each command after it's done its own substitutions. – Henning Makholm Apr 19 '18 at 12:49
  • @HenningMakholm Thanks, I've edited. You may want to post an answer. Lok Lam Cheng had commented on the question to suggest :, but it should be an answer (especially if correct) and that comment doesn't explain why one should expect it to work. In a directory with hello.c and no makefile, where make hello compiles hello.c to hello, I found make CC=: hello behaved according to what you are saying. – Eliah Kagan Apr 19 '18 at 13:04
  • 2
    Unfortunately, for this particular Makefile (it uses erlang.mk), using : doesn't work. Being explicit about /bin/true is probably the best way to do it. – Roger Lipscombe Apr 19 '18 at 14:22

While I agree that using the full path to true would be the best solution, I'd like to note what's probably by far the most common way to avoid real command execution: sticking an echo in front of it. So:

make TOOL=echo
  • I think this is sometimes useful when it's important one be reminded that one suppressed whatever action TOOL would otherwise do. Without -s or equivalent, make emits redundant information, because both make and the echo command run by make separately emit output. For example, when I run make CC=echo hello in a directory that has hello.c and no makefile, I get echo hello.c -o hello as the first line of output and hello.c -o hello as the second. But some builds use (or the user may add) -s, and then it's helpful. make -s CC=echo hello gives just hello.c -o hello. – Eliah Kagan Apr 19 '18 at 15:23
  • (which might still be useful if the commands involve shell expansions, so you can get a clearer idea of what's being run, if interested) – muru Apr 19 '18 at 15:57

You can always make your own command that does nothing but return a zero exit status. Some options:

  • an appropriately named symbolic link to /bin/true

  • an empty shell script

  • a nearly empty C program:

    int main() {
        return 0;
  • A good name for such a program would be noop or no-op. – arp Apr 20 '18 at 22:15

Create a symbolic link in the working directory to /bin/true named something like skip. Thus...

skip -> /bin/true

Then the make line can be ...

make TOOL=./skip

Here's a way to do it with slightly more characters:

function T() { /bin/true; }

After you've done it once you can re-execute it just by using the name T.

false; T; echo $?
  • 3
    Could you please explain how this function can be invoked from a Make variable value (to be of use in the situation in question)? – David Foerster Apr 20 '18 at 22:17

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.