![我无法在子 shell 上设置 ulimit](https://linux22.com/image/1194139/%E6%88%91%E6%97%A0%E6%B3%95%E5%9C%A8%E5%AD%90%20shell%20%E4%B8%8A%E8%AE%BE%E7%BD%AE%20ulimit.png)
我有一个 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&
每当它在 5 分钟后自行运行时,mybashscript.sh 就无法正常运行,因为未应用 ulimit 设置。我该如何修复它?
答案1
您的代码有两个明显的问题:
第一的,您需要在后面的字符串周围使用单引号,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
您可能不会注意到在非交互式 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
甚至是 shell 内置命令printf
(利用其格式化功能) 代替echo
。
此外,您使用附加运算符>>
可能会表明mycronscript.sh
已经有一些行/代码并且您正在附加它...如果是这种情况那么您最终会得到一个混乱的无法使用的脚本...如果不是这种情况,则使用运算符>
覆盖脚本文件的内容。
第二,您需要以提升的权限运行脚本,即sudo
为了增加最大用户进程限制或最大打开文件限制...等,使用ulimit
上面的硬限制...所以它需要看起来像这样:
sudo bash mainscript.sh
注意:如果您使用sudo
脚本并同时将其发送到后台,例如:
sudo bash mycronscript.sh &
您可能需要将其带回前台,fg
以便能够输入密码sudo
,否则脚本将在后台等待密码,而不会在您不注意的情况下执行...因此,要么使用sudo
上述方法运行主前台脚本,要么使用例如登录到root shell,sudo -i
然后在那里运行脚本,sudo
而无需要特别小心因为您运行的每个命令都将以root
权限运行。
我也不热衷于使用sudo
内部脚本。
另外,请注意ulimit
是 shell 的内置命令,它控制在当前 shell 下启动的进程可用的资源,并且不会对其他外部 shell 产生影响。
另请注意,只要不超过设置的硬限制,您就可以root
使用该选项降低/增加无需权限的软限制......如下所示:-S
ulimit -S -u {N}
其中{N}
,数字小于硬限制...您可以使用以下命令打印例如用户进程的硬限制:
ulimit -H -u
或对所有限制使用:
ulimit -H -a
您也可以root
在没有权限的情况下降低硬限制,例如:
ulimit -H -u {N}
或者,当未指定任何选项时,-H
和都是默认值,如下所示:-S
ulimit -u {N}
但是,没有特权你就不能再次提出它root
。