Re: printf has weird behaviour when parsing zero padded numbers

2009-06-22 Thread Greg Wooledge
On Fri, Jun 19, 2009 at 11:05:27AM -0700, bitozoid wrote:
> >         edua...@ceo ~ $ printf "%02d\n" 8
> >         -bash: printf: 8: invalid number

> Sorry, not a bug, but octal representation. Really sorry.

Others will make the same mistake (it's very common), so for the
benefit of people searching for answers, here are the two workarounds
I know:

1) Strip all leading zeroes from strings that you intend to use as numbers
   before you use them.

2) Force interpretation of the string as a base 10 number by prefixing it
   with 10# inside a numeric context.

Number 1 is trickier than it seems at first glance.  There are two ways
(that I know) to do it:

 a) Use extended glob notation to remove multiple leading zeroes in a
single regular expression:

shopt -s extglob
n=${n##+(0)}

 b) Use a loop to remove all leading zeroes, one at a time:

while [[ $n = 0* ]]; do n=${n#0}; done

Number 2 is usually simpler in practice:

x=$((10#$n + 1))   # and so on




Re: printf has weird behaviour when parsing zero padded numbers

2009-06-22 Thread Chris F.A. Johnson
On Mon, 22 Jun 2009, Greg Wooledge wrote:

> On Fri, Jun 19, 2009 at 11:05:27AM -0700, bitozoid wrote:
> > > edua...@ceo ~ $ printf "%02d\n" 8
> > > -bash: printf: 8: invalid number
> 
> > Sorry, not a bug, but octal representation. Really sorry.
> 
> Others will make the same mistake (it's very common), so for the
> benefit of people searching for answers, here are the two workarounds
> I know:
> 
> 1) Strip all leading zeroes from strings that you intend to use as numbers
>before you use them.
> 
> 2) Force interpretation of the string as a base 10 number by prefixing it
>with 10# inside a numeric context.
> 
> Number 1 is trickier than it seems at first glance.  There are two ways
> (that I know) to do it:
> 
>  a) Use extended glob notation to remove multiple leading zeroes in a
> single regular expression:
> 
> shopt -s extglob
> n=${n##+(0)}

   Or, with standard globbing:

${n#"${n%%[!0]*}"}


>  b) Use a loop to remove all leading zeroes, one at a time:
> 
> while [[ $n = 0* ]]; do n=${n#0}; done
> 
> Number 2 is usually simpler in practice:
> 
> x=$((10#$n + 1))   # and so on


-- 
   Chris F.A. Johnson, webmaster 
   ===
   Author:
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)




feature request: more complete set -e

2009-06-22 Thread Marc Weber
Hi,

I stumbled about another bash problem today:

for item in $(false);
  echo $item
done || { echo for failed; }

doesn't fail. I think it's bad that there is no
  set -e 

like switch which really catches all failures of this kind.

If you want to ignore non zero exit status you can always use || true.

Of course the workaround is obvious: use

  dummy_var=$(false)
  for item in $dummy_var;
echo $item
  done || { echo for failed; }

However you have to remeber this pitfall.

I know that some scripts may depend on the current behaviour.
So what about adding a new switch beeing more strict?

Sincerly
Marc Weber