Bash `ulimit-t`在shell和OSs之间完全不可移植?

Bash `ulimit-t`在shell和OSs之间完全不可移植?,bash,shell,signals,zsh,ulimit,Bash,Shell,Signals,Zsh,Ulimit,更新:这已不再是一个问题,而是一个总结。哦,好吧 bash、dash和zsh都带有一个内置命令ulimit。每个都有一个选项-t,它接受一个数字作为参数,可以理解为进程可能消耗的CPU时间(以秒为单位)。此后,将向他们发送一个信号。有这么多是清楚的 不过,还有很多不清楚的地方。我发现有些事情是出乎意料的。特别是,您得到的行为取决于shell和底层操作系统。我创建了一个表格,总结了变化的程度。我还包括一个脚本的代码,我用它自动获得这些结果。最后一个测试需要root权限,如果您注释掉test\u s

更新:这已不再是一个问题,而是一个总结。哦,好吧

bash、dash和zsh都带有一个内置命令
ulimit
。每个都有一个选项
-t
,它接受一个数字作为参数,可以理解为进程可能消耗的CPU时间(以秒为单位)。此后,将向他们发送一个信号。有这么多是清楚的

不过,还有很多不清楚的地方。我发现有些事情是出乎意料的。特别是,您得到的行为取决于shell和底层操作系统。我创建了一个表格,总结了变化的程度。我还包括一个脚本的代码,我用它自动获得这些结果。最后一个测试需要root权限,如果您注释掉
test\u shell\u sudo$shell
,则可以阻止它运行

| | Darwin/zsh | Darwin/bash | FreeBSD/zsh | FreeBSD/bash | FreeBSD/dash | Linux/zsh | Linux/bash | Linux/dash | | ulimit -t sets | soft limit | both limits | soft limit | both limits | both limits | soft limit | both limits | both limits | | ulimit -t gets | soft limit | soft limit | soft limit | soft limit | soft limit | soft limit | soft limit | soft limit | | Hard limits can be set below the soft limit | yes | no | yes | yes | yes | yes | no | no | | Soft limits can be set above the hard limit | yes | no | yes | no | no | yes | no | no | | Hard limits can be raised without privileges | yes | no | yes | no | no | yes | no | no | | soft signal | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | | hard signal | SIGXCPU | SIGXCPU | SIGKILL | SIGKILL | SIGKILL | SIGKILL | SIGKILL | SIGKILL | | Number of SIGXCPUs sent | one | one | one | one | one | multiple | multiple | multiple | | Raising soft beyond hard limit raises it | yes | impossible* | yes | no | no | yes | impossible* | impossible* | * even as root || Darwin/zsh | Darwin/bash | FreeBSD/zsh | FreeBSD/bash | FreeBSD/dash | Linux/zsh | Linux/bash | Linux/dash| |ulimit-t集|软限|两个限|软限|两个限|两个限|软限|两个限|两个限| |ulimit-t得到|软限|软限|软限|软限|软限|软限|软限| |硬限制可以设置在软限制以下|是|否|是|是|是|是|否|否| |软限制可以设置在硬限制之上|是|否|是|否|否|是|否|否| |硬限制可以在没有特权的情况下提高|是|否|是|否|是|否|否| |软信号| SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU | SIGXCPU| |硬信号| SIGXCPU | SIGXCPU | SIGKILL | SIGKILL | SIGKILL | SIGKILL | SIGKILL | SIGKILL| |发送的SIGxCPU数|一|一|一|一|多|多|多| |将软限制提升到硬限制之外会提升软限制|是|不可能|是|否|是|不可能|不可能|| *连根
#/usr/bin/env bash
获取_sigcode(){
/垃圾箱/压井-l|
tr'\n[a-z]'[a-z]'|
awk-v name=$1'
{for(i=1;i&1>/dev/null'
}
sigxcpus_sent=`f`
echo“发送的SIGXCPUs数:${SIGXCPUs_sent}”
}
测试_shell_sudo(){
外壳=1美元
echo_强调“用sudo测试shell:$shell”
f(){
sudo$shell-c'ulimit-St 1;ulimit-Ht 1;ulimit-St 2&&ulimit-Ht'\
2> /dev/null;
}
out=`f`;ret=$?;
如果[[$ret==0]];则
以美元计价
1)
将“软”提升到“硬”之上,表示“不”;;
2)
将“软”提升到“硬”之上;;
*)
呼应意外;;
以撒
其他的
将“软”提升到“硬”之上
fi
echo“将软提升到硬限制之外会提升它:${Raising_soft_beyond_hard}”
}
main(){
echo“平台测试:$(uname)”
sigxcpu=$(获取sigxcpu代码)
sigkill=$(get_sigcode KILL)
信号SIGXCPU的回波号:${SIGXCPU}
信号SIGKILL的回波数:${SIGKILL}
创建跑步者
创建计数器
回声
对于zsh bash dash中的shell;do
哪个$shell>/dev/null | | continue;
测试shell$shell
回声
完成
对于zsh bash dash中的shell;do
哪个$shell>/dev/null | | continue;
test_shell_sudo$shell
回声
完成
}
主要的

还提供了一个更好的表。

首先,以下是ulimit的绝对规则,包括shell在内的所有进程都被限制为:

  • 任何人都可以降低自己的硬限制
  • 提高硬限制需要特权
  • 软限制可以上下提升,只要它小于硬限制
考虑到这一点:

  • 我是否应该再次提高先前调用ulimit设置的限制
  • 软限制,是的。硬限制,不

    bash似乎认为不,而zsh认为是

    Bash默认设置硬限制。Zsh默认设置软限制

    Zsh记录了这一点,但bash没有。在任何情况下,
    strace
    告诉所有人:

    $ strace -e setrlimit zsh -c 'ulimit -t 1'
    setrlimit(RLIMIT_CPU, {rlim_cur=1, rlim_max=RLIM64_INFINITY}) = 0
    
    $ strace -e setrlimit bash -c 'ulimit -t 1'
    setrlimit(RLIMIT_CPU, {rlim_cur=1, rlim_max=1}) = 0
    
  • 我将收到什么信号
  • 如果您超过软CPU限制,您将无法继续。之后发生的事情在POSIX中没有定义。根据它的手册页,Linux将每秒重新发送SIGXCPU,直到达到硬限制为止,此时您将被SIGKILL

    我有宽限期吗

    您可以通过设置软限制来选择自己的宽限期

    警告: 在
    zsh
    上,设置硬限制而不同时设置软限制将导致限制应用于子对象而不是外壳:

    zsh% ulimit -H -t 1
    zsh% ( while true; do true; done )   # is a child, soon killed
    zsh% while true; do true; done       # not a child, never dies
    
    如果同时设置两个限制,它们将应用于当前shell,如
    bash

    zsh% ulimit -SH -t 1
    zsh% while true; do true; done       # will now die, just like bash
    

    我不知道这背后的理由是什么。

    这些限制是对用户的警告。内核中还设置了软限制和硬限制(通常),即它们不是由shell管理的。同样,软限制被认为是一种警告,表明可能很快就会达到限制,程序可以将其进程限制扩展到硬限制,但不能再扩展(除非是root)。请参见
    man2getrlimit
    man2setrlimit
    ,了解底层的C API。是的,我测试并确认了这一切。你能给出一系列以非根用户身份运行的命令来演示你所看到的吗?使用(a)和(b)你尝试了这个答案中演示的while循环,而不是你自己的
    zsh% ulimit -SH -t 1
    zsh% while true; do true; done       # will now die, just like bash