Bash script size limit?

I have a bash script, which when running on RHEL or OS X gives the following error:

line 62484: syntax error near unexpected token `newline '

line 62484: `-o_gz '

This is an automatically generated script, to bypass the restrictions imposed by the computing cluster grid engine, used in my company. All of this is made up of a bunch of almost identical to if/elif . I do not see anything special in the line where the error comes. When I run the script before the start of the error strings, it works without problems. It makes me think that maybe bash script length limit. The only reference I could find on the Internet, was the comment from iAdjunct .

Part of the script around error looks like this (with some simplifications):

 . . . . 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 ] . . . . \ . . . . 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 ] . . . . \ . . . . 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 ] . . . . 

Does this ring any call to someone?

+5
source share
1 answer

Yes, this restriction to bash .

This is not a script size limit; rather, it is a restriction on the depth of the parser stack, which leads to a limitation of the complexity of some designs. In particular, this will limit the number of proposals elif in the statement if about 2500.

There is a long analysis of the problem with respect to another syntax (iterated pipes) in response to a question on the site StackExchange Unix and the Linux .

Operators

case does not have this restriction, and an example that you give, certainly looks good match for operator case .

(The difference with the operators of case is that the grammar for conditional statements if , as the designers of pipes, is recursive, and grammar for operators case remains recursive. Due to space constraints if different from the restrictions on the channels, so that's what grammatical construction for offers elif has another symbol, so each iteration uses four stack slots instead of three.)

If the operator case does not work for you - or even if this is the case, you can try to create a pre-compiled binary search tree operators 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 

Since each full operator if takes only one stack node after its recognition, limiting the complexity is at a depth of nesting operators if , rather than on the number of proposals. As an added bonus, he will perform far fewer comparisons in the average case.

If you have no alternative but sequential list of conditions, you can use the separate instructions 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 

Unconventional indent is intended to illustrate a simple conversion program: simply replace each elif on break;fi;if and surround all with the help of while (to provide a target for break s.)

+8
source

All Articles