From: Wayne on
Francis Moreau wrote:
> On Mar 13, 8:48 am, Decare <dec...(a)yeah.net> wrote:
>> Is there any to determine whether a string
>> is a integer or not? For example,
>>
>
> not sure which integer formats you want to support but:
>
> expr $s \* 0 2>&1 >/dev/null
>
> might do it.

Many folk forget that expr has a powerful reg exp (BRE) match
operator of ":":

LC_ALL=C expr -- X"$ARG" : 'X[+-]\{0,1\}[[0-9]\{1,\}$' >/dev/null

But the BRE syntax is ugly as is the necessary "--" and "X", so
I prefer the more readable grep version:

LC_ALL=C printf -- "$ARG" | grep -Exqe '(-|\+)?[0-9]+'

or the single process (but a bit uglier) awk version:

LC_ALL=C awk 'BEGIN { exit !(ARGV[1] ~ /^[-+]?[0-9]+$/) }' "$ARG"

Since some older system use "egrep" and not "grep -E", either
the expr or awk versions are likely more portable.

Also in all cases, you need to ensure LC_COLLATE is set to C (or POSIX),
or the range "[0-9]" may not work. On POSIX systems you could always
use "[[:digit:]]" but that won't work on older, non-POSIX systems.
Setting LC_COLLATE=C (or LC_ALL=C) should work fine on POSIX systems
and have little effect on older systems where character class ranges
may not be locale sensitive.

Finally, the regular expressions used here will match "-0" and
"+0", and fail on "0x00A9" and "1E3" (which are valid Integer
representations in some cases). But while the OP didn't specify
the purpose of the "Integer" match, that is unlikely to matter
for most uses.

--
Wayne
From: Chris F.A. Johnson on
On 2010-03-17, Wayne wrote:
> Francis Moreau wrote:
>> On Mar 13, 8:48 am, Decare <dec...(a)yeah.net> wrote:
>>> Is there any to determine whether a string
>>> is a integer or not? For example,
>>>
>>
>> not sure which integer formats you want to support but:
>>
>> expr $s \* 0 2>&1 >/dev/null
>>
>> might do it.
>
> Many folk forget that expr has a powerful reg exp (BRE) match
> operator of ":":

Most folk realize that an external command is not necessary, and a
simple case statement will suffice.

--
Chris F.A. Johnson, author <http://shell.cfajohnson.com/>
===================================================================
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
===== My code in this post, if any, assumes the POSIX locale =====
===== and is released under the GNU General Public Licence =====
From: Janis on
On 16 Mrz., 19:48, Dominic Fandrey <kamik...(a)bsdforen.de> wrote:
> On 16/03/2010 18:34, Janis Papanagnou wrote:
>
>
>
>
>
> > Dominic Fandrey wrote:
> >> On 15/03/2010 18:56, Stephane CHAZELAS wrote:
> >>> 2010-03-15, 13:36(+01), Dominic Fandrey:
> >>> [...]
> >>>>> That will say that "foo<LF>1" is an integer, or that "\062" is
> >>>>> an integer (with an Unix echo), the result for "12\c" is
> >>>>> unspecified (unterminated line)...
> >>> [...]
> >>>> I cannot follow you here:
>
> >>>> $ echo "\062"
> >>>> \062
> >>> Your echo is not Unix conformant.
>
> >> You're talking about POSIX?
>
> >> Well, I don't really care about that. POSIX doesn't even define
> >> "local". How would anyone write shell scripts without "local"?
>
> > In ksh functions I use typeset to declare local variables. The "local"
> > keyword is unknown to that shell. Is "local" available in any shell
> > other than bash? Is "local" in any way "better" than "typeset", or
> > vice versa? Both, local and typeset, are non-standard, certainly shell
> > dependent. That makes your above claim sound silly.
>
> So ksh has something similar to local. Just proves that the thing
> is required, at least in my book. It looks like typeset is more
> portable, but ASH doesn't know it, so it's of no use to me.

No, 'typeset' is not "more" portable. As 'local' it is just *not*
portable.

>
> Recursive functions, without local or your typeset thing?
> That doesn't sound nice to me.

Donald Knuth, as a prominent example, implemented recusive functions
based on stacks. Not elegant but quite straightforward.

>
> Imagine you have ~100 functions and need to make up distinct variable
> names for each one? You end up with annoying prefixes and still
> haven't solved the recursion problem.

No prefixes. See above.

But I really wonder on what problems you're using shell programs on a
regular basis that you come to a conclusion that you "require" local
scope in functions.
Off the top of my head I cannot think of a general(!) recursive
program that I'd do efficiently in shell, where most shells don't even
support the most elementary data structures; either I'd have used an
appropriate language for the problem, or I've made something wrong if
the recursion appears as a blocker.
I had used recursive approaches in (a couple) shell programs as well,
but there was nothing in those solutions that - if I had no ksh
functions available - I wouldn't have been able to write based on a
set of (individually local scoped shell programs instead of a set of
shell functions.

>
> The feature is needed and POSIX doesn't define it.

POSIX defines a very limited subset of features, but those are
portable at least.
I disagree, though, that local scope is really needed. (Or to continue
that line of thought; that object orientation is really needed - just
to make apparent that we can continue our demands ad infinitum.) Use
shell programs as your scoped entities, or subshells, as proposed
elsewhere.

(I'd rather like to see that POSIX defines those features that are
simple and already available on modern shells, like ${ / / } and $
{ : : } etc., just BTW.)

Kornshell, for example, goes in the direction of enhancing the shell
language to become a programming language with more data structure
support; there's no end to see. I really like programming ksh with its
advanced features, but you still won't have a Real Programming
Language available that way. Neither fish nor fowl, and constantly
changing, you can't rely on availability of features on a version that
is only slightly older, and not portable to any other shell for sure.

>
> If you stick to POSIX you're stuck.

Not seriously. Use those features that are, while non-standard, at
least available with all modern shells.

Janis

>
> Regards
>

From: Jon LaBadie on
Janis wrote:
> On 16 Mrz., 19:48, Dominic Fandrey <kamik...(a)bsdforen.de> wrote:
....
>> So ksh has something similar to local. Just proves that the thing
>> is required, at least in my book. It looks like typeset is more
>> portable, but ASH doesn't know it, so it's of no use to me.
>
> No, 'typeset' is not "more" portable. As 'local' it is just *not*
> portable.
>
....
>
>> The feature is needed and POSIX doesn't define it.
>
> POSIX defines a very limited subset of features, but those are
> portable at least.
> I disagree, though, that local scope is really needed.

But certainly useful for writing reusable functions and keeping
them as a "library".

> ... Use
> shell programs as your scoped entities, or subshells, as proposed
> elsewhere.

Yes, there are workarounds, each with their own pros&cons.

> (I'd rather like to see that POSIX defines those features that are
> simple and already available on modern shells, like ${ / / } and $
> { : : } etc., just BTW.)

As Stephane pointed out, local is available in dash, bash, zsh, and
pdksh besides the typeset of ksh88 and ksh93. Certainly that qualifies
as "already available on modern shells". But maybe local scoping is
not a "simple" as your prefered POSIX enhancements. Myself, I'd like
to see local function scoping and your string manipulations standardized.
From: Janis on
On 17 Mrz., 15:18, Jon LaBadie <jlaba...(a)aXcXm.org> wrote:
> Janis wrote:
> > On 16 Mrz., 19:48, Dominic Fandrey <kamik...(a)bsdforen.de> wrote:
> ...
> >> So ksh has something similar to local. Just proves that the thing
> >> is required, at least in my book. It looks like typeset is more
> >> portable, but ASH doesn't know it, so it's of no use to me.
>
> > No, 'typeset' is not "more" portable. As 'local' it is just *not*
> > portable.
>
> ...
>
> >> The feature is needed and POSIX doesn't define it.
>
> > POSIX defines a very limited subset of features, but those are
> > portable at least.
> > I disagree, though, that local scope is really needed.
>
> But certainly useful for writing reusable functions and keeping
> them as a "library".

There's a lot useful, yes. Rarely "required"; which was the strong
term in question.

For example, ksh functions (as opposed to POSIX functions) - while not
the same - have a lot structural and semantical similarities with
separate shell programs (arguments, getopts, signal traps, local scope
(with typeset), etc.). I can write my recursive functions (if I like
so) in ksh functions or shell programs; the structural and semantical
differences are comparably small and (from a plain coding POV) a
"workaround" (as you call that below) not very different. I can build
my libraries (and of course have done so) on the shell program
abstraction level. (I've also used function libraries, and even ksh
specific user-defined "builtin" functions. Rarely "required".) For the
question of efficiency there could be an argument in favour of
functions[*]. But considering the "recursive functions" as one
apparent application where efficiency is probably most crucial, it
seems - from my limited perspective - either rarely needed or
typically other solutions are preferable. (Still interested in
examples, for example, where you'd require time critical recursion
where there are no better solutions.) WRT libraries of functions there
are also different features in the various shells supported; non-
portable, usually.

[*] Similar to the (arguable) introduction of threads in addition to
processes.

>
>  > ...  Use
>
> > shell programs as your scoped entities, or subshells, as proposed
> > elsewhere.
>
> Yes, there are workarounds, each with their own pros&cons.
>
> > (I'd rather like to see that POSIX defines those features that are
> > simple and already available on modern shells, like ${ / / } and $
> > { : : } etc., just BTW.)
>
> As Stephane pointed out, local is available in dash, bash, zsh, and
> pdksh besides the typeset of ksh88 and ksh93.  Certainly that qualifies
> as "already available on modern shells".

Ksh maintains a strong place in the set of the "modern shells"; if
some feature is not supported by any of ksh, bash, or zsh, that
feature should IMO be used reluctantly.

In c.u.s I try to avoid 'typeset' (and 'local'), but I regularily
suggest, for example, despite not being POSIX, the string manipulation
functions. Because the latter is available in all the prominent shells
that you find on not too old systems.

> But maybe local scoping is
> not a "simple" as your prefered POSIX enhancements.  Myself, I'd like
> to see local function scoping and your string manipulations standardized.

I would like to see a consistent standard on a feature level that is
sufficiently high; POSIX is not.
And I would like to see a clearly visible and converging development
path with all the shells so that any standard has a chance to define a
large enough subset; which is also not the case.

The Kornshell typeset, BTW, has more purposes than being just a local
variable declaration - so hardly to believe that they agree on that.

Janis