出于不相关的目的,我被迫生成一个仅适用于 posix sh 的脚本。
在我的脚本中,我检查了系统是否允许创建 coredump,那么如果限制设置为 0,我希望脚本尝试运行ulimit -c unlimited
。
我在脚本中尝试过,但没有成功:
sh -c "ulimit -c unlimited"
ulimit -c unlimited
在我的通用 zsh 终端中,尝试第一个命令失败了,但如果我运行 sh ,那么第二个命令手动它就可以工作。
因此,为了放置在更大的 posix sh 脚本中,我如何运行这些命令来启用核心转储?
答案1
ulimit
确实是未定义的标准,它似乎只知道ulimit -f
,所以我们不能指望标准来避免任何问题。
然而,ulimit -c unlimited
它适用于我尝试过的所有 shell:Bash、Dash(Debian 的/bin/sh
)、Busybox、zsh、ksh 和 yash。我不知道 BSD 上的 ksh 变体。
请注意,设置的资源限制ulimit
是从进程继承到其子进程的,因此脚本中的设置仅影响脚本启动的进程。也就是说,这sh -c "ulimit -c unlimited"
将是无用的:它只会更改特定 shell 的限制,该 shell 在设置限制后立即退出。
当然,设置限制可能会失败,例如可能设置硬限制,阻止您提高限制。因此,您可能需要对ulimit
调用进行一些错误检查:
if ! ulimit -c unlimited; then
echo "error: something went wrong when setting core dump limit" >&2
exit 1
fi
# do something here that might dump core
这应该适用于大多数 shell,但它看起来像在 zsh 中,ulimit
总是返回成功状态,即使失败也不会给出任何错误(很奇怪)。因此,在 zsh 中,您需要随后读取 limit 来检查它是否设置正确,例如:
ulimit -c unlimited
if [ "$(ulimit -c)" != unlimited ]; then
echo "error: core dump limit wasn't set" >&2
exit 1
fi
当然,您的系统可能还有其他可能影响核心文件创建的因素。
答案2
当前的 POSIX 文本列出:
ulimit [-H|-S] -a
ulimit [-H|-S] [-c|-d|-f|-n|-s|-t|-v] [newlimit]
所以 POSIX 标准确实包含ulimit -c corelimit
...
您可能错过了相关限制是由调用控制的,setrlimit()
并且该调用仅控制调用进程setrlimit()
或该进程子进程的限制。
由于您尝试调用ulimit ...
子 shell,因此这些设置仅适用于该子 shell 及其潜在的子 shell。
换句话说,您需要调用ulimit
当前的 shell 以使设置对您当前的工作环境有效。如果你喜欢快捷方式,你可以为该命令设置一个快捷alias
方式或编写一个脚本,但这样的脚本需要通过命令dot
(.)调用才能对你的工作 shell 生效。