7

我正在调试别人的代码,我遇到了一种情况,如果我试图故意编写它,我将不知道如何产生。它来自一个非常大的 Bash 脚本,由 Bash 4.1.2 在 CentOS 6 机器上运行。虽然整个程序非常庞大,但错误始终出现在以下函数中:

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}"
4

1 回答 1

9

错误E2BIG是指环境中的字节和 argv 列表的总和。脚本是否导出了大量(或大量)变量?跑printenv在前面wget看看发生了什么。

于 2012-08-24T23:44:03.523 回答