您收到此错误的原因是 make(尤其是 GNU make)尝试执行许多优化。其中之一是,如果命令看起来是一个不需要 shell 的简单命令,那么 make 将简单地通过 fork/exec 直接调用它而不运行 shell。如果该命令仅作为 shell 内置存在,那么这将不起作用。您的命令行ulimit -c 10000
是一个简单的命令,并且 ulimit 并没有被定义为只有 make 知道的 shell-builtin,所以 make 将尝试ulimit
直接 fork/exec。因此,解决您当前问题的一种方法是简单地添加一个对 shell 特殊的字符(最明显的是;
),这将暗示需要将该命令发送到 shell。
但是,这对您不起作用。
与上面 H2CO3 的评论完全相反:考虑到它提供的功能,它怎么可能是[内置的 shell]?您必须问自己的真正问题是相反的:考虑到它提供的功能,它怎么可能不是一个? ulimit 的手册页明确指出:ulimit 实用程序应设置或报告对 shell 及其子进程写入的文件施加的文件大小写入限制,并且进一步:由于 ulimit 影响当前 shell 执行环境,因此始终提供为一个shell常规内置。
您必须记住,UNIX 中的进程几乎不可能修改其父进程的任何方面。它只能修改自己或它调用的任何子进程。这包括环境变量、工作目录,还包括 ulimit 设置。
那么,很好,这如何适用于您的情况?您必须记住,make 配方中的每个逻辑行都是在单独的 shell中调用的。所以对于像这样的命令:
core: myprogram
ulimit -c 10000 ;
./myprogram
ulimit -c 0 ;
(添加分号以强制 shell)make 基本上调用的是这样的:
core: myprogram
/bin/sh -c 'ulimit -c 10000 ;'
/bin/sh -c './myprogram'
/bin/sh -c 'ulimit -c 0 ;'
如您所见,每个 ulimit 都在其自己的 shell 中调用,因此它实际上是无用的。它将修改该外壳的核心文件大小限制,然后外壳退出并且更改丢失,然后在具有原始 ulimit 的新外壳中调用您的程序,然后调用第三个外壳并将内核的 ulimit 设置为 0 (也无用)。
您需要做的是将所有这些命令放在一个逻辑行上,如下所示:
core: myprogram
ulimit -c 10000; ./myprogram
(您不需要重新设置限制,因为 shell 无论如何都会退出)。
附带说明一下,这就是为什么 make 不太担心这些 shell 内置函数的原因。在不需要使用诸如分号之类的特殊外壳字符的上下文中,基本上不可能使用这样的内置函数来产生任何效果。