我无法在子 shell 上设置 ulimit

Eri*_*kli 2 command-line bash scripts ulimit resource-limiting

我有一个 bash 脚本。该 bash 脚本需要每 5 分钟运行一次,因此我创建了以下代码块:

#!/bin/bash
ulimit -n 600000
ulimit -u 600000
echo -e "This is another bash script to run mybashscript.sh"

# Lets create mycronscript.sh
echo "#!/bin/bash
ulimit -n 600000
ulimit -u 600000
while true; do
sleep 300
bash mybashscript.sh
done" >> mycronscript.sh
bash mycronscript.sh&
Run Code Online (Sandbox Code Playgroud)

每当它在 5 分钟后自行运行时,mybashscript.sh 就无法正常运行,因为未应用 ulimit 设置。我该如何修复它?

Raf*_*ffa 5

您的代码有两个明显的问题:

首先,您需要在字符串后面使用单引号,echo以防止 shell 将!shebang 中的解释#!/bin/bash为在双引号内扩展的历史扩展字符...所以它需要如下所示:

echo '#!/bin/bash
ulimit -n 600000
ulimit -u 600000
while true; do
sleep 300
bash mybashscript.sh
done' >> mycronscript.sh
Run Code Online (Sandbox Code Playgroud)

当从非交互式 shell 中的脚本内部运行时(默认情况下未启用历史记录)与从交互式 shell 运行时相比,您可能不会注意到问题...但是,它可能/会咬住你(例如,它会自动运行最后一个命令,/bin/bsh例如,如果您之前使用/bin/bash scriptfile该命令运行过某个脚本,则该命令将立即运行,根本不需要您的确认)很快就会运行,例如当您的 shell 设置/环境变量更改为在非交互式 shell 中启用历史记录时。

但是,我会使用更好的格式化机制替代方案,例如此处文档,如下所示:

cat > mycronscript.sh <<EOF
#!/bin/bash
ulimit -n 600000
ulimit -u 600000
while true; do
sleep 300
bash mybashscript.sh
done
EOF
Run Code Online (Sandbox Code Playgroud)

甚至是内置的 shell printf利用其格式化功能)而不是echo.

另外,您对附加运算符的使用>>可能表明mycronscript.sh已经有一些行/代码并且您正在附加它...如果是这种情况,那么您最终会得到一个混乱的无法使用的脚本...如果不是这样如果是这样,则使用>运算符覆盖脚本文件的内容。

其次,您需要以提升的权限运行脚本,即sudo为了增加最大用户进程限制或最大打开文件限制...等等,使用ulimit高于硬限制...所以它需要看起来像这样:

sudo bash mainscript.sh
Run Code Online (Sandbox Code Playgroud)

注意:如果您sudo在脚本上使用并同时将其发送到后台,例如:

sudo bash mycronscript.sh &
Run Code Online (Sandbox Code Playgroud)

您可能需要将其带回前台,fg以便能够输入密码sudo,否则脚本将在后台等待密码,并且在您没有注意到的情况下不会执行...所以要么运行您的主前台如上所述,sudo或者您可以使用例如登录到 root shell,sudo -i然后在那里运行您的脚本,并且sudo非常小心,因为您运行的每个命令都将以root特权运行。

sudo我也不会热衷于使用内部脚本。

另外,请注意,它ulimit是一个内置 shell,它提供对在当前 shell 下运行的进程可用的资源的控制,并且对其他外部 shell 没有影响。

另外,请注意,只要不超过设置的硬限制,您就可以在没有root权限的情况下使用该选项降低/增加软限制...如下所示:-S

ulimit -S -u {N}
Run Code Online (Sandbox Code Playgroud)

其中{N}是小于硬限制的数字...您可以使用以下命令打印例如用户进程的硬限制:

ulimit -H -u
Run Code Online (Sandbox Code Playgroud)

或对于所有限制:

ulimit -H -a
Run Code Online (Sandbox Code Playgroud)

您也可以在没有root特权的情况下降低硬限制,例如:

ulimit -H -u {N}
Run Code Online (Sandbox Code Playgroud)

或者,当两个选项均未指定时,-H和都是默认值,并且:-S

ulimit -u {N}
Run Code Online (Sandbox Code Playgroud)

但是,如果没有特权,您就无法再次提出它root