6

With the following Makefile, GNU make runs the two commands in parallel. Since the first one takes time to finish, rm *.log is run before the log file is created, and fails.

dummy.pdf: dummy.tex
    tex dummy.tex &> /dev/null;
    rm *.log

The file dummy.tex one line: \bye (a short empty file for TeX). Replacing tex dummy.tex by any other command shows the same behaviour. Removing &> /dev/null would of course solve the problem, but it is not a very good option in my case, since the Makefile is provided by a third party.

Is it possible to prevent GNU make from doing anything in parallel? (the flag -j 1 does not help).

EDIT: output to the terminal:

bruno@bruno-laptop:~/LaTeX/make-experiment$ make
tex dummy.tex &> /dev/null;
rm *.log
rm: cannot remove `*.log': No such file or directory
make: *** [dummy.pdf] Error 1
bruno@bruno-laptop:~/LaTeX/make-experiment$ This is TeX, Version 3.1415926 (TeX Live 2009/Debian)
(./dummy.tex )
No pages of output.
Transcript written on dummy.log.

2 Answers 2

11

Actually, you don't have a problem with make, but with your command:

tex dummy.tex &> /dev/null;

Runs 'tex' in the background. You don't need to remove '>/dev/null', but '&' is sending 'tex' to the background.

Try this, it must be fine for you:

tex dummy.tex > /dev/null;

or run everything in the same subshell, like this:

(tex dummy.tex > /dev/null;rm *.log)

or less sane, this:

if test 1 = 1; then tex dummy.tex > /dev/null;rm *.log; fi

PD: &> is an extension provided by some shells (including bash) to redirect both stdout and stderr to the same destination, but it's not portable, you should use '>/dev/null 2>&1' instead. (Thanks @Gilles)

Cheers

13
  • 8
    @Bruno: &> is an extension provided by some shells (including bash) to redirect both stdout and stderr to the same destination, but it's not portable. It's likely that the author of the Makefile has bash as his /bin/sh, but you have ash or ksh which doesn't support this syntax. Commented Mar 17, 2011 at 19:50
  • 2
    Yes, but then, you should use '>/dev/null 2>&1' instead
    – D4RIO
    Commented Mar 17, 2011 at 20:00
  • 1
    @BrunoLeFloch: Check if /bin/sh is a symbolic link. Note that /bin/sh may not be the shell you're using interactively. Instead of mycommand &>dest (csh/bash/zsh-specific), you can write mycommand >dest 2>&1, which is portable to any shell that make might use. Commented Mar 17, 2011 at 20:03
  • 1
    @BrunoLeFloch: AFAIK $SHELL is your user shell as defined in /etc/passwd, but makefile will try to use /bin/sh.
    – D4RIO
    Commented Mar 17, 2011 at 20:10
  • 1
    @D4RIO: perhaps add the > /dev/null 2>&1 version to your answer to make it complete? Commented Mar 17, 2011 at 20:20
2

Er? make parallelizes targets (with -j); it never reorders commands within a target.

2
  • I would agree... But it does :-s. Commented Mar 17, 2011 at 19:42
  • Your comment just saved the day. I had saved -j8 as a global value for MAKEFLAGS and was wondering why everything was not being executed in order!! Commented Jun 25, 2022 at 17:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .