我正在调试别人的代码,如果我试图故意编写代码,我会遇到一些我不知道如何生成的情况。它来自一个非常大的Bash脚本,由CentOS 6盒子上的Bash 4.1.2运行。虽然整个程序是巨大的,但错误始终发生在以下函数中:
get_las() {
echo "Getting LAS..."
pushd ${ferret_workdir} >& /dev/null
#Download:
if [ ! -e ${las_dist_file} ] || ((force_install)) ; then
echo "Don't see LAS tar file ${las_dist_file}"
echo "Downloading LAS from ${las_dist_file} -to-> $(pwd)/${las_dist_file}"
echo "wget -O '${las_dist_file}' '${las_tar_url}'"
wget -O "${las_dist_file}" "${las_tar_url}"
[ $? != 0 ] && echo " ERROR: Could not download LAS:${las_dist_file}" && popd >/dev/null && checked_done 1
fi
popd >& /dev/null
return 0
}
如果我允许脚本在原始环境中从头开始运行,当到达此部分时,它将吐出以下错误并死掉:
Don't see LAS tar file las-esg-v7.3.9.tar.gz
Downloading LAS from las-esg-v7.3.9.tar.gz -to-> /usr/local/src/esgf/workbench/esg/ferret/7.3.9/las-esg-v7.3.9.tar.gz
wget -O 'las-esg-v7.3.9.tar.gz' 'ftp://ftp.pmel.noaa.gov/pub/las/las-esg-v7.3.9.tar.gz'
/usr/local/bin/esg-product-server: line 428: /usr/bin/wget: Argument list too long
ERROR: Could not download LAS:las-esg-v7.3.9.tar.gz
请注意,我甚至在那里有一个调试回声来证明参数只是两个小字符串。
如果我让程序在上面的位置出错,然后立即从同一个期望的脚本重新运行它,唯一的变化就是它已经完成了这个之前的所有阶段并且正在检测并跳过它们,此部分将正常执行,没有错误。这种行为在我的测试盒上100%可重复 - 如果我清除运行代码的所有痕迹,此后第一次运行就会爆炸,随后的运行将会很好。
我唯一能想到的是,我在Bash本身遇到了一些模糊的错误,它以某种方式导致它无形地泄漏MAX_ARG_PAGES内存,但我想不出任何理论上的方法来实现这一点,所以我问这里。
到底发生了什么以及如何让它停止(没有像重新编译内核那样的极端措施,只是为它投入更多内存)?
更新:要回答评论中的问题,第428行是
wget -O "${las_dist_file}" "${las_tar_url}"
答案 0 :(得分:9)
错误E2BIG
是指环境中的字节和argv列表的总和。脚本是否导出了大量(或巨大)的变量?在printenv
之前运行wget
,看看发生了什么。