Bash脚本大小限制?
我有一个bash脚本,当在RHEL或OS X上运行时,会出现以下错误:
这是一个自动生成的脚本,用于解决我公司使用的Grid Engine计算群集引入的限制.它全部由一堆几乎相同的if / elif组成.我看不出错误来自哪一行有什么特别之处.当我在错误行之前运行脚本的开头部分时,它可以正常工作.这让我觉得可能有一些bash脚本长度限制.我在网上找到的唯一参考是comment by iAdjunct. 围绕错误的脚本部分看起来像这样(有一些简化): . . . . elif [ $task_number -eq 2499 ] then /some/tool/executable -use_prephased_g -m /some/text/file -h /some/zipped/file -l -int 45063854 46063853 -Ne 20000 -o /some/output/file -verbose -o_gz #==============> ****THIS IS LINE 62484**** elif [ $task_number -eq 2500 ] then /some/tool/executable -use_prephased_g -m /some/other/text/file -h /some/other/zipped/file -l -int 98232182 99232182 -Ne 20000 -o /some/other/output/file -verbose -o_gz elif [ $task_number -eq 2501 ] . . . . 这对任何人都响铃吗?
是的,这是bash的限制.
这不是脚本大小限制;相反,它是对解析器堆栈深度的限制,它具有限制某些结构的复杂性的效果.特别是,它会将if语句中的elif子句的数量限制为大约2500. 在我对Unix & Linux stackexchange站点的a question的回答中,对于不同的句法结构(迭代管道)有一个更长的分析问题. case语句没有这个限制,你提供的示例肯定看起来像是case语句的良好匹配. (与case语句的不同之处在于if条件语句的语法,如管道构造的语法,是正确的递归,而case语句的语法是递归的.对if语句的限制与管道限制不同的原因是elif子句的语法结构有一个符号,所以每次重复使用四个堆栈槽而不是三个.) 如果case语句不适合你 – 或者即使它也适用 – 你可以尝试构建if语句的预编译二进制搜索树: if (( task_number < 8 )); then if (( task_number < 4 )); then if (( task_number < 2 )); then if (( task_number < 1)); then # do task 0 else # do task 1 fi; elif (( task_number < 3 )); then # do task 2 else # do task 3 fi elif (( task_number < 6 )); then if (( task_number < 5 )); then # do task 4 else # do task 5 fi elif (( task_number < 7 )); then # do task 6 else # do task 7 fi elif (( task_number < 12 )); then if (( task_number < 10 )); then if (( task_number < 9 )); then # do task 8 else # do task 9 fi elif (( task_number < 11 )); then # do task 10 else # do task 11 fi elif (( task_number < 14 )); then if (( task_number < 13 )); then # do task 12 else # do task 13 fi elif (( task_number < 15 )); then # do task 14 else # do task 15 fi 因为每个完整的if语句在识别后仅占用单个堆栈节点,所以复杂性限制将取决于if语句的嵌套深度而不是子句的数量.作为额外的奖励,它将在一般情况下执行更少的比较. 如果除了顺序条件列表之外别无选择,则可以使用单独的if语句: while :; do if condition1; then # do something break; fi; if condition2; then # do something break; fi; if condition3; then # do something break; fi; if condition4; then # do something break; fi # No alternative succeeded break done 非常规的缩进旨在说明简单的程序转换:简单地用break; fi替换每个elif; if和if一段时间包围整个事物(为休息提供目标) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |