openSUSE Forums > Archives > SF Archives > ARCHIVES - 64-bit » Bash Script Problem

Go Back   openSUSE Forums > Archives > SF Archives > ARCHIVES - 64-bit
Forums FAQ Members List Search Today's Posts Mark Forums Read


ARCHIVES - 64-bit Questions specific to 64-bit systems running SUSE Linux
(Questions that apply to both 32-bit and 64-bit systems should be posted in the appropriate mixed architecture forums)

 
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 09-Apr-2008, 23:20
Howard Rogers
Guest
 
Posts: n/a
Default

I have a bash shell script which does the following:

SHMAX = `cat /proc/sys/kernel/shmmax`
MEMSZ = `cat /proc/meminfo | grep MemTotal | awk '{print $2}'`
let "MEMSZ *= 1024"
let "MEMSZ /= 2"
let "MEMSZ += 16777216"
if [ $SHMAX -lt $MEMSZ ]; then
SHMAX = $MEMSZ
fi

The aim is to say, "Check what RAM you're using. If the current size of your maximum shared memory segment is less than about 50% of that total RAM amount, set your maximum shared memory to be about 50% of your total RAM".

The thing works fine on 32-bit Suse, Centos, Fedora, Ubuntu ...you name it. It even works without incident on 64-bit Centos 5. But on 64-bit OpenSuse 10.3, it produces this error:

line 223: [: 18446744073709551615: integer expression expected

The line number referenced is the point at which $SHMAX is compared to $MEMSZ. The stupidly long number reported in the error message is the value of /proc/sys/kernel/shmmax in a completely default x86_64 installation of Suse 10.3 in a server that has 2GB of physical RAM.

I am guessing that the enormous value of SHMMAX in my fresh installation of OpenSuse 64-bit is causing the numeric comparison with my MEMSZ variable to blow up.

On Centos 5.1 (64-bit), for example, SHMMAX by default on the same server is set to 68,719,476,736 (which I believe is 64GB). That's a couple of orders of magnitude less than OpenSuse's default, which would appear to be in the region of a couple of Exabytes!

My question is, therefore, what can I do about that (apart from the obvious one of forcibly setting SHMAX to a sensibly large value before starting). Is there some way of allowing a bash shell script to do math precision greater than what it does by default? Is there some sort of comparison operator I can use that would cope with such daft numbers? Is my shell script code (I am no expert!) hopelessly wrong in some trivial respect?

Any pointers gratefully received...
  #2 (permalink)  
Old 09-Apr-2008, 23:34
ken_yap
Guest
 
Posts: n/a
Default

bash integer arithmetic is tied to the size of integer on the particular platform, and may also differ from version to version of bash. For maximum portability, you don't want to use bash to do calculation on large numbers. Use a programming language that supports bignums, like python or perl, to do those calculations. Or scale your numbers down.
  #3 (permalink)  
Old 09-Apr-2008, 23:55
Howard Rogers
Guest
 
Posts: n/a
Default

Quote:
bash integer arithmetic is tied to the size of integer on the particular platform, and may also differ from version to version of bash. For maximum portability, you don't want to use bash to do calculation on large numbers. Use a programming language that supports bignums, like python or perl, to do those calculations. Or scale your numbers down.
[/b]
Thank you for the reply.

Sometimes, suggesting people do things a completely different way is an entirely valid option. But not in this case, because bash is all I've got to work with! The script is intended to work with completely default OS installations, where the existence of perl and python cannot be assumed.

Can I therefore clarify: are you saying that the error message received is definitely caused by the size of the default setting of SHMMAX? And that this causes the error because bash cannot cope with such large integers? There is nothing in my code I could change that would allow the comparison to take place successfully?

I was only guessing about the integer size being the issue, but if you could point me to some documentation to that effect, I would be grateful.

Presumably, the fix in my case (python and perl not being options) would be to simply forcefully set SHMMAX to some arbitrarily large number that bash CAN cope with? No other options (in bash)? Apart from the obvious one of scaling things down to MBs or GBs and doing the comparison in those units, rather than in bytes?
  #4 (permalink)  
Old 10-Apr-2008, 00:15
ken_yap
Guest
 
Posts: n/a
Default

Yes, I'm saying that bash arithmetic cannot handle arbitrarily large integers. Bash integers were intended to do counting and simple sums, not arbitrary math.

If you can't use perl or python, you could use a small helper program that will probably be in all major Linux distros by default, called bc. It might even be in non-Linux distros. It goes back quite a long way in Unix history.

Try this:

echo '12345678901234 * 111 / 12' | bc
  #5 (permalink)  
Old 10-Apr-2008, 00:26
Howard Rogers
Guest
 
Posts: n/a
Default

Quote:
Yes, I'm saying that bash arithmetic cannot handle arbitrarily large integers. Bash integers were intended to do counting and simple sums, not arbitrary math.

If you can't use perl or python, you could use a small helper program that will probably be in all major Linux distros by default, called bc. It might even be in non-Linux distros. It goes back quite a long way in Unix history.

Try this:

echo '12345678901234 * 111 / 12' | bc
[/b]
Well, I wouldn't myself call merely enquiring as to the DEFAULT value of a kernel parameter 'arbitrary math', nor seeking to compare the DEFAULT settings of two kernel parameters... but that's a side issue. Perhaps it depends on the precise definition of the word "arbitrary"!

As a matter of curiosity, I would love to see where it is documented what the precision limits of SuSE bash scripts' math are, exactly.

It would be helpful to understand how the bc utility can be used to assist the comparisons between the two numbers I indicated earlier. I've looked at the man pages for bc, and it leaves me cold, I'm afraid!

In the meantime, I've just hard-coded that 64-bit Suse's SHMMAX should be set to 64GB and the comparison after that works fine...
  #6 (permalink)  
Old 10-Apr-2008, 00:43
ken_yap
Guest
 
Posts: n/a
Default

I don't think bash's integer arithmetic limits are explicitly documented. It's probably just a consequence of using the int type in the C code. Remember that shells want to be lean, and linking in an arbitrary precision numeric library isn't going to help.

Bc has full expression handling. So you could do this:

result=`echo 12345 > 1234' | bc`
if [ "$result" -ne 0 ]
then
echo "12345 is greater than 1234"
fi
  #7 (permalink)  
Old 10-Apr-2008, 01:02
Howard Rogers
Guest
 
Posts: n/a
Cool

Quote:
I don't think bash's integer arithmetic limits are explicitly documented. It's probably just a consequence of using the int type in the C code. Remember that shells want to be lean, and linking in an arbitrary precision numeric library isn't going to help.

Bc has full expression handling. So you could do this:

result=`echo 12345 > 1234' | bc`
if [ "$result" -ne 0 ]
then
echo "12345 is greater than 1234"
fi
[/b]
Wonderful. Thank you for your help! Since there's an extra quotation mark in your reply (easily done!) and it doesn't exactly relate back to the original question, here's the code which now runs perfecftly without making arbitrary changes to a kernel parameter's default value:

result=`echo $SHMAX \< $MEMSZ | bc`
if [ "$result" -ne 0 ]; then
SHMAX=$MEMSZ
fi

Works fine... very grateful!
 

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




 

Search Engine Friendly URLs by vBSEO 3.3.0 RC2