[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ksh's select, almost, in portable shell
From: |
Ralf Wildenhues |
Subject: |
Re: ksh's select, almost, in portable shell |
Date: |
Wed, 17 Sep 2008 23:25:38 +0200 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
* Peter Seebach wrote on Wed, Sep 17, 2008 at 08:07:19PM CEST:
>
> But you can implement a shell function such that
>
> while func_select var in args
> do
> done
>
> is equivalent (nearly) to
>
> select var in args
> do
> done
>
> I enclose func_select below. Weaknesses:
> 1. Newline after prompt. (Solving this portably seemed like too much work.)
Grab the settings of ECHO_C, ECHO_N, ECHO_T from Autoconf, and use them.
> 2. "in args" is not optional; it can't implicitly use address@hidden
>
> So far as I can tell, this is basically solid. What'd I miss?
>
> func_select () {
> func_select_args=0
> if expr "$1" : "^[_a-zA-Z][_a-zA-Z0-9]*$" > /dev/null; then
FWIW, expr expressions are always anchored, so there is no need for more
anchoring (another instance below). But can't you avoid a fork here,
like
case $1 in
[!_a-zA-Z]* | *[!_a-zA-Z0-9]*) usage "$1";;
esac
> func_select_var=$1
> else
> echo >&2 "func_select: '$1' is not a valid variable name."
> return 1
> fi
> shift 1
'shift N' is not so portable. Just drop the 1.
> for func_select_arg
> do
> func_select_args=`expr $func_select_args + 1`
> eval func_select_a_$func_select_args=\$func_select_arg
> done
This again forks a lot. I'd use a shell function to factor between
$(()) and expr, so that only shells without the former use the latter
and fork (Autotest and Libtool do this). Likewise below.
> if expr "$REPLY" : '^[1-9][0-9]*$' > /dev/null; then
case $REPLY in
0* | *[!0-9]* ) bad ... ;;
esac
Otherwise, looks good to me (untested).
Cheers,
Ralf