我只是偶然发现了这个问题。我试着写一个非常基本的Makefile
目标:
core: myprogram
ulimit -c 10000
./myprogram
ulimit -c 0
我们的想法是将核心大小限制设置为正确的值,使程序崩溃,然后将核心大小限制重置为零。当我调用此规则时,收到以下错误消息:
$ make core
cc -Wall -Wextra -m32 -g -o example example.c
ulimit -c 100000
make: ulimit: Command not found
make: *** [core] Error 127
首先,我有点惊讶,但我认为问题来自ulimit
是内置shell的事实。而且,令人惊讶的是(至少对我而言),这些内置函数无法从Makefile
调用。
此外,ulimit
既可以是内置函数(我的Debian就是这种情况)或仅限二进制程序(/usr/bin/ulimit
)。
所以,我的问题很简单,如何以一种优雅和可移植的方式解决这个问题,并从Makefile内部调用内置函数?
答案 0 :(得分:13)
您收到此错误的原因是make(特别是GNU make)尝试执行许多优化。其中一个是如果命令出现是一个不需要shell的简单命令,那么make将直接通过fork / exec调用它而不运行shell。如果该命令仅作为内置shell存在,那么这将不起作用。您的命令行ulimit -c 10000
是一个简单的命令,并且ulimit没有被定义为只有shell内置的make,所以make会尝试直接fork / exec ulimit
。因此,解决您的直接问题的方法是简单地添加一个特殊于shell的字符(最明显的是;
),这将暗示需要将此命令发送到shell。 / p>
但是,这对你不起作用。
与H2CO3上面的评论完全相反:考虑到它提供的功能,它怎么可能是[内置shell]?你要问自己的真正问题恰恰相反: how鉴于它提供的功能,它可能不是一个吗? ulimit的手册页明确指出: ulimit实用程序应设置或报告对shell写入的文件施加的文件大小写入限制及其子进程,进一步:由于ulimit会影响当前的shell执行环境,因此它始终作为常规内置shell提供。
您必须记住,UNIX中的进程几乎不可能修改其父进程的任何方面。它只能修改自身或它调用的任何子进程。这包括环境变量,工作目录,还包括ulimit设置。
那么,好,这对你的情况如何?您必须记住,make配方中的每个逻辑行都是在单独的shell 中调用的。所以对于像这样的命令:
core: myprogram
ulimit -c 10000 ;
./myprogram
ulimit -c 0 ;
(添加分号以强制使用shell)基本上调用的是:
core: myprogram
/bin/sh -c 'ulimit -c 10000 ;'
/bin/sh -c './myprogram'
/bin/sh -c 'ulimit -c 0 ;'
如您所见,每个ulimit都在自己的shell中调用,因此它实际上没用。它将修改该shell的核心文件大小限制,然后shell退出并且更改丢失,然后在具有原始ulimit的新shell中调用您的程序,然后调用第三个shell并将core的ulimit设置为0 (也没用)。
您需要做的是将所有这些命令放在一个逻辑行上,如下所示:
core: myprogram
ulimit -c 10000; ./myprogram
(你不需要设置限制,因为shell无论如何都会退出。)
作为旁注,这个是为什么make不太担心这些shell内置的原因。在不需要使用像分号这样的特殊shell字符的上下文中,这样的内置基本上不可能用于任何效果。
答案 1 :(得分:3)
任何Makefile
的默认shell都是sh
。如果必须使用特定shell的内置函数,请在Makefile
:
SHELL:=bash
请注意,这是糟糕的做法,因为您的Makefile
应该在任何计算机上运行,而不仅仅是bash
安装。
如果您想支持任何一种变体(外部与内置),您可以检查bash
resp的可用性。 ulimit
通过which
设置一个包含要使用的命令的变量(ulimit
与bash -c "ulimit"
),具体取决于该检查的结果。
编辑:MadScientist对ulimit
的“当前仅限shell”方面绝对正确。为了文档的目的,我会完整地保留这个答案,但它对perror的具体问题没有帮助。
答案 2 :(得分:2)
你可以说:
core: myprogram
$(shell /bin/bash -c "ulimit -c 10000")
./myprogram
$(shell /bin/bash -c "ulimit -c 0")
答案 3 :(得分:0)
在官方GNU make文档(http://www.gnu.org/software/make/manual/make.html)第5.3.2章中,它说“用作shell的程序取自变量SHELL。如果你的makefile中没有设置这个变量,程序/ bin / sh用作shell。“ 您可以将SHELL设置为/ bin / bash。
答案 4 :(得分:0)
简短答案:在命令末尾添加分号(;)。这样,您将使用内置工具调用FULL Shell。
ulimit -c 10000;
代替
ulimit -c 10000