[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Is this an IFS bug in getopts?
From: |
Anshul Narula |
Subject: |
Re: Is this an IFS bug in getopts? |
Date: |
Tue, 26 Apr 2011 22:37:54 +0530 (IST) |
Its not related to getopts
Run the following(with set -x probably):
foo() { echo "$1" ;}
foo -i
oIFS=$IFS
IFS=-
foo -i
IFS=$oIFS
foo() { echo $1 ;}
foo -i
IFS=-
foo -i
If you run your code with set -x, you would notice that the real cause is that
$err_opts is not quoted. You set IFS and are bitten by word splitting.
----- Original Message ----
> From: Steven W. Orr <steveo@syslang.net>
> To: bug-bash@gnu.org
> Sent: Tue, 26 April, 2011 6:41:49 PM
> Subject: Re: Is this an IFS bug in getopts?
>
> On 4/26/2011 12:02 PM, DJ Mills wrote:
> > On Tue, Apr 26, 2011 at 11:42 AM, Steven W. Orr<steveo@syslang.net> wrote:
> >
> >> GNU bash, version 4.0.35(1)-release (x86_64-redhat-linux-gnu)
> >>
> >> I ran a program that was supposed to die with an error message that said:
> >>
> >> Invalid format: example: 2.103.269.28-1-3
> >>
> >> Instead, it died with:
> >>
> >> i -- Invalid format: example: 2.103.269.28-1-3
> >>
> >> I traced the problem back to a call to getopts. It turns out that when I
> >> called getopts, I had set IFS='-'. It never occurred to me that I could
> >> impact the function of getopts by setting IFS.
> >>
> >> The old code was this:
> >> DRVREV="$1"
> >> IFS=-
> >> set -- $DRVREV
> >> (( $# == 3 )) || die -i -- 'Invalid format: example: 2.103.269.28-1-3'
> >>
> >> I can fix the problem easily by saying
> >>
> >> oldIFS="$IFS"
> >> DRVREV="$1"
> >> IFS=-
> >> set -- $DRVREV
> >> IFS="$oldIFS"
> >> (( $# == 3 )) || die -i -- 'Invalid format: example: 2.103.269.28-1-3'
> >>
> >> So here we are.
> >> 1. Should getopts be documented to say that it uses IFS?
> >> 2. Should getopts be hardcoded to use the dash as the option delimiter?
> >> 3. Is the current functionality correct the way it is and I'm just looking
> >> at it wrong?
> >>
> >> TIA :-)
> >>
> >>
> > I don't see getopts anywhere in that example. It would also help to know
> > what your
> > die() function is, as I suspect that may be causing the issue.
>
> Fair enough.
>
> err was created as a simple echo that went to stderr. Then I added -i so
> that
>it would allow itself to read from stdin after it processed its arguments.
>
> die is just a call to err followed by a call to exit. It captures the -i and
>passes it through to err. It also accepts a -s to specify an exit code.
>
> Also, the die call is routinely made with -- because sometimes the args to
> be
>echoed can begin with a -.
>
> err()
> {
> typeset opt
> typeset opt_i=0
> OPTIND=1
> while getopts ':-i' opt "$@"
> do
> case $opt in
> i)
> opt_i=1
> ;;
> *)
> echo "Illegal option to err: ${@:((OPTIND-1)):1}" 1>&2
> exit 1
> ;;
> esac
> done
> shift $((OPTIND-1))
> (( $# != 0 )) && echo -e "$@" 1>&2
> (( opt_i )) && cat 1>&2
> }
>
> die()
> {
> typeset opt
> typeset opt_s=1
> typeset opt_i=0
> typeset err_opts=
> OPTIND=1
> while getopts ':is:' opt "$@"
> do
> case $opt in
> i)
> opt_i=1
> err_opts='-i'
> ;;
> s)
> opt_s=$OPTARG
> ;;
> *)
> err "Illegal option to die: ${@:((OPTIND-1)):1}"
> exit 1
> ;;
> esac
> done
> shift $((OPTIND-1))
> err $err_opts -- "$@"
> exit $opt_s
> }
>
>
>
> -- Time flies like the wind. Fruit flies like a banana. Stranger things have
>
>.0.
> happened but none stranger than this. Does your driver's license say Organ
..0
> Donor?Black holes are where God divided by zero. Listen to me! We are all-
000
> individuals! What if this weren't a hypothetical question?
> steveo at syslang.net
>
>