Bash `ulimit-t`在shell和OSs之间完全不可移植?
更新:这已不再是一个问题,而是一个总结。哦,好吧 bash、dash和zsh都带有一个内置命令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
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在内的所有进程都被限制为:
- 任何人都可以降低自己的硬限制
- 提高硬限制需要特权
- 软限制可以上下提升,只要它小于硬限制
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
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