value too great for base (error token is "0008")

View: New views
8 Messages — Rating Filter:   Alert me  

value too great for base (error token is "0008")

by Dobromir Romankiewicz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Configuration Information [Automatically generated, do not change]:
Machine: i486
OS: linux-gnu
Compiler: gcc
Compilation
CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I../bash -I../bash/include -I../bash/lib   -g -O2 -Wall
uname output: Linux debian 2.6.26-2-686 #1 SMP Wed Aug 19 06:06:52 UTC 2009
i686 GNU/Linux
Machine Type: i486-pc-linux-gnu

Bash Version: 3.2
Patch Level: 39
Release Status: release

Description:
        [
Well... Just paste those functions into your text konsole, and compare to my
results:

:1() { x1=0; x2=0; x3=0; x4=7
echo $[$x1$x2$x3$x4]
}
The result is 7.

And run this code:
:2() { x1=0; x2=0; x3=0; x4=8
echo $[$x1$x2$x3$x4]
}
It crashes with message:
bash: 0008: value too great for base (error token is "0008").

:3() { x1=0; x2=0; x3=0; x4=8
echo $[$x4$x2$x3$x1]
}
works well, printing 8000.

Similar codes
:4() { x1=0; x2=0; x3=0; x4=8
s=$x1$x2$x3$x4
echo $[$s]
}
or
:5() { x1=0; x2=0; x3=0; x4=8
s=$x1$x2$x3$x4
echo $[s]
}
goes the same way like :2
Oh, if x4=9 it goes the same way as if x4=8. I didn't check higher values.
]


signature.asc (204 bytes) Download Attachment

Re: value too great for base (error token is "0008")

by Bob Proulx :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dobromir Romankiewicz wrote:
> And run this code:
> :2() { x1=0; x2=0; x3=0; x4=8
> echo $[$x1$x2$x3$x4]
> }
> It crashes with message:
> bash: 0008: value too great for base (error token is "0008").

Thank you for the report.  But you have run into Bash FAQ E8.

Numbers with leading zeros are read as octal constants.  Octal is
composed of '0' through '7'.  The number '8' is too large to be an
octal number.

  $ echo $((0008))
  bash: 0008: value too great for base (error token is "0008")

To have the number read as a decimal number the leading zeros must be
removed.

  $ echo $((8))
  8

Note also that the use of $[expression] for $((expression)) is
documented as deprecated and to be removed in a future version.
Better to use $((expression)) instead.

Bob



Re: value too great for base (error token is "0008")

by Greg Wooledge :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Nov 03, 2009 at 05:37:45PM -0700, Bob Proulx wrote:
> Dobromir Romankiewicz wrote:
> > bash: 0008: value too great for base (error token is "0008").

> Numbers with leading zeros are read as octal constants.  Octal is
> composed of '0' through '7'.  The number '8' is too large to be an
> octal number.
>
>   $ echo $((0008))
>   bash: 0008: value too great for base (error token is "0008")
>
> To have the number read as a decimal number the leading zeros must be
> removed.
>
>   $ echo $((8))
>   8

If removing the leading zeroes would be difficult for you, then you can
force the arithmetic expression to use base 10 by prefixing the variable
with "10#".  Thus:

  month=$(date +%m)     # Can produce "08" etc.
  next_month=$(( (10#$month == 12) ? 1 : 10#$month+1 ))
  echo $next_month

On the other hand, removing a single leading zero is not difficult:

  month=$(date +%m) month=${month#0}   # Removing leading 0
  next_month=$(( ($month == 12) ? 1 : $month+1 ))

Removing multiple leading zeroes, however, requires either a loop, or the
use of extended globs.  A variant of this question (removing leading/trailing
spaces) appears at <http://mywiki.wooledge.org/BashFAQ/067>.  Although it
looks like someone removed my loop solution... grrr.

> Note also that the use of $[expression] for $((expression)) is
> documented as deprecated and to be removed in a future version.
> Better to use $((expression)) instead.

$((...)) is also POSIX-compliant.  Please do switch.



Re: value too great for base (error token is "0008")

by Eric Blake :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Greg Wooledge on 11/4/2009 6:23 AM:
> On the other hand, removing a single leading zero is not difficult:
>
>   month=$(date +%m) month=${month#0}   # Removing leading 0

Not portable.  Assigning the same variable twice in the same statement has
different order of operations in some shells.  Use:

month=$(date +%m); month=${month#0}

instead.

>   next_month=$(( ($month == 12) ? 1 : $month+1 ))
>
> Removing multiple leading zeroes, however, requires either a loop, or the
> use of extended globs.

Not true.  You can do it via POSIX and without a loop by using an
intermediate variable:

foo=00081
bar=${foo%%[!0]*}
foo=${foo#$bar}}

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@...
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrxgn0ACgkQ84KuGfSFAYDyCACg0suH5IFGv+4dOe5Bf3kyBExR
R20AoM+U/AP6tqrF0QpEEYWgvjfx2m+H
=aC1b
-----END PGP SIGNATURE-----



Re: value too great for base (error token is "0008")

by Chris F.A. Johnson-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 4 Nov 2009, Eric Blake wrote:

> According to Greg Wooledge on 11/4/2009 6:23 AM:
> > On the other hand, removing a single leading zero is not difficult:
> >
> >   month=$(date +%m) month=${month#0}   # Removing leading 0
>
> Not portable.  Assigning the same variable twice in the same statement has
> different order of operations in some shells.  Use:
>
> month=$(date +%m); month=${month#0}
>
> instead.
>
> >   next_month=$(( ($month == 12) ? 1 : $month+1 ))
> >
> > Removing multiple leading zeroes, however, requires either a loop, or the
> > use of extended globs.
>
> Not true.  You can do it via POSIX and without a loop by using an
> intermediate variable:
>
> foo=00081
> bar=${foo%%[!0]*}
> foo=${foo#$bar}}

   Or even without an intermediate variable:

foo=${foo#${foo%%[!0]*}}

   (Though I prefer the variable for legibility.)

--
   Chris F.A. Johnson, webmaster         <http://woodbine-gerrard.com>
   ===================================================================
   Author:
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)



Re: value too great for base (error token is "0008")

by Dobromir Romankiewicz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thank you for your answers, I'll check more carefully before I'll send next
bug report - if I'll find it, of course.
That was silly. For my excuse I just would like to say I'm not coder. I
sometime prepare some scripts, if I need bot's help, or executables (for
fun).
The point here was that 2 kinds of variables were needed. Integer number as
while counter, and 4 digits string, as a part of filenames - i had add
leading zeros to get this working with filesystem I can't change or even
list.
I have solved my function writting it in diferent way, but your tips are going
to be usefull while making others.
Thank you all


signature.asc (204 bytes) Download Attachment

Re: value too great for base (error token is "0008")

by Greg Wooledge :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Nov 04, 2009 at 11:26:56PM +0100, Dobromir Romankiewicz wrote:
> Thank you for your answers, I'll check more carefully before I'll send next
> bug report - if I'll find it, of course.
> That was silly. For my excuse I just would like to say I'm not coder.

Heh.  I *am* a coder, and I've been tripped up by leading zeroes causing
a value to be treated as octal in more than one language.  (Bash and Tcl.)
It's a subtle and difficult thing to guard against, in these typeless
or weakly-typed scripting languages.

> The point here was that 2 kinds of variables were needed. Integer number as
> while counter, and 4 digits string, as a part of filenames - i had add
> leading zeros to get this working with filesystem I can't change or even
> list.

The general approach here is that whenever you're dealing with something
as a number, you must not have any leading zeroes on it; or you must
force bash to treat it as base 10, with the "10#" prefix.  Then, when
you're all done with the arithmetic and you're ready to put the number
in a filename, use printf to pad it to however wide you need.  Thus,

n=10
n=$(($n * 3 + 7)) # whatever
filename=app$(printf %05d $n).log



Re: value too great for base (error token is "0008")

by Chris F.A. Johnson-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 5 Nov 2009, Greg Wooledge wrote:

> On Wed, Nov 04, 2009 at 11:26:56PM +0100, Dobromir Romankiewicz wrote:
> > Thank you for your answers, I'll check more carefully before I'll send next
> > bug report - if I'll find it, of course.
> > That was silly. For my excuse I just would like to say I'm not coder.
>
> Heh.  I *am* a coder, and I've been tripped up by leading zeroes causing
> a value to be treated as octal in more than one language.  (Bash and Tcl.)
> It's a subtle and difficult thing to guard against, in these typeless
> or weakly-typed scripting languages.
>
> > The point here was that 2 kinds of variables were needed. Integer number as
> > while counter, and 4 digits string, as a part of filenames - i had add
> > leading zeros to get this working with filesystem I can't change or even
> > list.
>
> The general approach here is that whenever you're dealing with something
> as a number, you must not have any leading zeroes on it; or you must
> force bash to treat it as base 10, with the "10#" prefix.  Then, when
> you're all done with the arithmetic and you're ready to put the number
> in a filename, use printf to pad it to however wide you need.  Thus,
>
> n=10
> n=$(($n * 3 + 7)) # whatever
> filename=app$(printf %05d $n).log

   Faster is:

printf -v filename "app%05d.log" "$n"

--
   Chris F.A. Johnson, webmaster         <http://woodbine-gerrard.com>
   ===================================================================
   Author:
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)