我们有一个由cron调用的shell脚本,并以root身份运行。
此脚本输出日志记录和调试信息,并且在某个特定点失败。这一点根据脚本创建的输出量而有所不同(例如,如果我们启用更多的调试输出,它会更快失败)。
但是,如果直接以用户身份调用脚本,那么它可以正常运行。
我们已经创建了一个简化的测试用例来演示这个问题。
脚本是:
#!/bin/bash
function log_so () {
local msg="$1"
if [ -z "${LOG_FILE}" ] ; then warn_so "It's pointless use log_so() if LOG_FILE variable is undefined!" ; return 1 ; fi
echo -e "${msg}"
echo -e "${msg}" >> ${LOG_FILE}
(
/bin/true
)
}
LOG_FILE="/usr/local/bin/log_bla"
linenum=1
while [[ $linenum -lt 2000 ]] ; do
log_so "short text: $linenum"
let linenum++
done
在死亡之前达到的最高值是244(通过cron调用时)。
其他一些搜索建议使用函数中的no-op子shell并调用/ bin / true但不仅这不起作用,子shell选项在主脚本中是不可行的。
我们也尝试更改root的文件描述符限制,但这没有帮助,并尝试同时使用#!/ bin / sh和#!/ bin / bash作为脚本。
我们在Ubuntu 10.04 LTS上使用bash 4.1.5(1)-release。
对于解决方法的任何想法或建议都将不胜感激。
答案 0 :(得分:1)
用手打开fd然后清理它怎么样?我没有使用bash 4.1进行测试,但它可能有所帮助。
LOG_FILE="/usr/local/bin/log_bla"
exec 9<> "$LOG_FILE"
function log_so () {
local msg="$1"
if [ -z "${LOG_FILE}" ] ; then warn_so "It's pointless use log_so() if LOG_FILE variable is undefined!" ; return 1 ; fi
echo -e "${msg}"
echo -e "${msg}" >&9
return 0
}
linenum=1
while [[ $linenum -lt 2000 ]] ; do
log_so "short text: $linenum"
let linenum++
done
exec 9>&-