为什么我得到 "Makefile:1: *** missing separator. Stop." 而 "set -e"?
Why do I get "Makefile:1: *** missing separator. Stop." with "set -e"?
我有一个 单行 Makefile 抛出以下错误:Makefile:1: *** missing separator. Stop
。我知道 dozens of duplicate questions 有相同的错误消息,但其中大多数建议与不使用制表符或神秘的特殊字符有关。
$ cat -e -v -t Makefile
set -e$
$ make
Makefile:1: *** missing separator. Stop.
据我所知,没有神秘的特殊字符。也许有些字符 cat -e -v -t
没有显示?
以下工作正常,所以我猜这不是我的 make
安装的问题:
$ cat -v -e -t Makefile
foo:$
^Iecho "Foo"$
$ make
echo "Foo"
Foo
一些相关版本和shell信息。
$ make --version
GNU Make 3.81
$ echo [=14=]
-bash
编辑:查看@AProgrammer 的评论
请注意,无论我在 set -e
下面有什么,它都会抛出相同的错误消息。
$ cat -e -v -t Makefile
set -e$
$
foo:$
^Iecho "foo"$
$ make
Makefile:1: *** missing separator. Stop.
编辑 2:
注意添加 #!/bin/bash
会引发相同的错误消息。
$ cat -e -v -t Makefile
#!/bin/bash$
set -e$
$
foo:$
^Iecho "foo"$
$ make
Makefile:2: *** missing separator. Stop.
编辑 3:
运行 set -e
在我的 shell 上似乎直接工作(它按预期退出失败的 make
调用)。
$ set -e
$ make
Makefile:2: *** missing separator. Stop.
Saving session...completed.
Deleting expired sessions...11 completed.
[Process completed]
绝对没有理由 make
能够在规则之外解释任意 shell 命令。
如果你想在出现错误时立即退出规则,有几种方法可以做到,或多或少是可移植的。
首先,规则中的每一行都由 shell 的单独实例执行。这意味着如果您不手动合并它们(使用 \
和 ;
),如果每行一个命令,您将获得所需的行为。
然后您可以使用 set -e
作为可能需要它的少数规则的一部分。例如;
foo:
set -e; for i in a b c d; mkdir $$i; done
使用 GNU Make,您可以更改用于调用 shell 的标志,另外传递 -e
:
.SHELLFLAGS=-ec
用POSIXmake,可以改成shell。我不知道是否支持传递标志,但 GNU Make 似乎支持:
SHELL=/bin/sh -e
但您始终可以传递一个包装器,根据需要设置标志:
SHELL=/path/to/mywrapper
其中 mywrapper
为
#!/bin/sh
exec /bin/sh -e "$@"
我有一个 单行 Makefile 抛出以下错误:Makefile:1: *** missing separator. Stop
。我知道 dozens of duplicate questions 有相同的错误消息,但其中大多数建议与不使用制表符或神秘的特殊字符有关。
$ cat -e -v -t Makefile
set -e$
$ make
Makefile:1: *** missing separator. Stop.
据我所知,没有神秘的特殊字符。也许有些字符 cat -e -v -t
没有显示?
以下工作正常,所以我猜这不是我的 make
安装的问题:
$ cat -v -e -t Makefile
foo:$
^Iecho "Foo"$
$ make
echo "Foo"
Foo
一些相关版本和shell信息。
$ make --version
GNU Make 3.81
$ echo [=14=]
-bash
编辑:查看@AProgrammer 的评论
请注意,无论我在 set -e
下面有什么,它都会抛出相同的错误消息。
$ cat -e -v -t Makefile
set -e$
$
foo:$
^Iecho "foo"$
$ make
Makefile:1: *** missing separator. Stop.
编辑 2:
注意添加 #!/bin/bash
会引发相同的错误消息。
$ cat -e -v -t Makefile
#!/bin/bash$
set -e$
$
foo:$
^Iecho "foo"$
$ make
Makefile:2: *** missing separator. Stop.
编辑 3:
运行 set -e
在我的 shell 上似乎直接工作(它按预期退出失败的 make
调用)。
$ set -e
$ make
Makefile:2: *** missing separator. Stop.
Saving session...completed.
Deleting expired sessions...11 completed.
[Process completed]
绝对没有理由 make
能够在规则之外解释任意 shell 命令。
如果你想在出现错误时立即退出规则,有几种方法可以做到,或多或少是可移植的。
首先,规则中的每一行都由 shell 的单独实例执行。这意味着如果您不手动合并它们(使用 \
和 ;
),如果每行一个命令,您将获得所需的行为。
然后您可以使用 set -e
作为可能需要它的少数规则的一部分。例如;
foo:
set -e; for i in a b c d; mkdir $$i; done
使用 GNU Make,您可以更改用于调用 shell 的标志,另外传递 -e
:
.SHELLFLAGS=-ec
用POSIXmake,可以改成shell。我不知道是否支持传递标志,但 GNU Make 似乎支持:
SHELL=/bin/sh -e
但您始终可以传递一个包装器,根据需要设置标志:
SHELL=/path/to/mywrapper
其中 mywrapper
为
#!/bin/sh
exec /bin/sh -e "$@"