“ulimit -Su”是否限制在交互式登录子shell和其中创建的tmux会话中创建的用户进程数?

Sam*_*Sam 5 bash ksh process tmux ulimit

几个月前,我编写了一组 bash 脚本,使用 tmux 在 AIX 7.1 服务器上创建一个简单的 IDE。我的一个脚本中存在一个错误,有时会非常快速地生成用户进程,直至达到 ulimit 设置的限制。这种情况很少发生(大约每月一次),而且我已经花了几个小时来追踪这个错误,但没有成功,所以我决定暂时,我可以简单地将我的软用户进程限制设置为低于硬限制(例如 100 而不是 1024),这样当我的错误再次出现时,服务器上的其他用户不会有明显的性能下降。不幸的是,“ulimit -Su 100”似乎在 AIX 7.1 上的 bash 中不起作用,但它在 ksh 中起作用。我已经执行了以下解决方法:

使 ksh 成为默认 shell:

$ chsh [username] /usr/bin/ksh
Run Code Online (Sandbox Code Playgroud)

将以下内容写入 ~/.kshrc:

ulimit -Su 100  # works in ksh, but not in bash
/bin/bash -il   # start bash as an interactive login shell
exit            # once bash exits, exit from ksh, too
Run Code Online (Sandbox Code Playgroud)

所以现在,每次我创建一个 shell 时,ksh 都会设置软用户进程限制并启动 bash 作为一个交互式登录 shell(我仍然希望 ~/.bash_profile 获得来源)。现在我想知道,在 ksh 中设置的用户进程限制是否仍然会在 bash 子 shell 中强制执行?在顶级 bash 子shell中,我运行了以下命令:

$ ulimit -Sa
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) unlimited
pipe size            (512 bytes, -p) 64
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
Run Code Online (Sandbox Code Playgroud)

如您所见,用户进程限制设置为 1024。

我的另一个主要问题是知道 ksh 中设置的限制是否包括在 bash 子 shell 中的 tmux 会话中创建的进程。

其他细节:每当我在 tmux 中创建一个新窗格时,我相当确定 ksh 被调用, ~/.kshrc 被获取,bash 被启动,就像正常一样。我相信是这种情况,因为每个新创建的 tmux 窗格的标题都是“ksh”(tmux 窗格的默认标题是前台当前进程的名称),但我看到的是 bash 提示而不是ksh 提示。

这有点啰嗦,所以我想我会省略更多的细节,除非被要求。

编辑 1:奇怪的行为

看看当我尝试使用“ulimit -Su”(无参数)获取用户进程限制时会发生什么,使用和不使用 truss:

$ truss ulimit -Su 2>| truss.out
100
$ ulimit -Su
1024
Run Code Online (Sandbox Code Playgroud)

也许我使用的工具有误,但这看起来很奇怪。这些命令在 tmux 中运行。

编辑 2:附加信息

这些命令是从常规 bash 提示符运行的——没有子 shell 或 tmux。

$ truss ksh -c "ulimit -Su 100" 2>&1 | grep limit
getrlimit64(9, 0x2FF1B988)                      = 0
setrlimit64(9, 0x2FF1B988)                      = 0
$ truss bash -c "ulimit -Su 100" 2>&1 | grep limit
appulimit(1005, 0)                              = 0x2001C000
bash: line 0: ulimit: max user processes: cannot modify limit: A system call received a parameter that is not valid.
Run Code Online (Sandbox Code Playgroud)

pab*_*ouk 3

资源限制简介

类 Unix 系统中的资源限制由系统getrlimit()调用控制setrlimit()。这些限制是按进程配置的,并在生成新进程时继承(例如通过fork())。这意味着如果您想从 shell 设置限制,则必须将命令内置到 shell 中(而不是作为子进程执行)。确实ulimit是许多 shell 中的内置函数,包括kshbash

观察到的行为

的“内置”性质解释了和ulimit中的不同行为。kshbash

用户进程数的限制 ( ulimit -u) 由系统调用设置setrlimit(RLIMIT_NPROC, ...)。在旧版本的 AIX 中,不支持 RLIMIT_NPROC。<1> AIX 6.1 中添加了该支持<2 第 5.4.4 节实施的更改>因此ulimitinksh使用setrlimit64()正确。可能bash是为了与旧版本的 AIX 兼容而编译的,并且无法控制此限制。

结论

您可以使用ulimit内置的 from ksh,所有子进程都将继承配置的限制。一般来说,shell 和进程与强制和保持资源限制无关,除非它们显式调用setrlimit().

选择

在 AIX 中,还有一个替代方案也应该适用于旧版本的 AIX:

chdev -l sys0 -a maxuproc=100
Run Code Online (Sandbox Code Playgroud)

参见3、4