sh says: test "$1" = "" when $1="-b"

sh says: test "$1" = "" when $1="-b"

Post by Karl Anders » Thu, 03 Dec 1992 14:42:38



I'm trying to write a dinky sh script which contains the following
while loop:

while test "$1" != ""
do
        case "$1" in
                -i) input=$2; shift ;;
                [+\-][0-9]*) version=$1 ;;
                -v) month=$2; day=$3; shift; shift ;;
                -d) del="yes" ; echo "XX" ;;
                -*) echo "get: unknown argument $1" 1>&2; exit 1 ;;
                *)  file=$1 ;;
        esac
        shift
done

The echo "XX" statement is only for debugging.

Anyway, when $1 is "-d", the test statement exits false, and the -d)
line in the case statement is not executed.  Any arguments after this
one are ignored by the while statement.  When I change the line in the
case statemet to -b) , the script works as expected.

What gives?

k

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by Jos V » Thu, 03 Dec 1992 21:58:13



>I'm trying to write a dinky sh script which contains the following
>while loop:
>while test "$1" != ""
>do
>        case "$1" in
>                -i) input=$2; shift ;;
>                [+\-][0-9]*) version=$1 ;;
>                -v) month=$2; day=$3; shift; shift ;;
>                -d) del="yes" ; echo "XX" ;;
>                -*) echo "get: unknown argument $1" 1>&2; exit 1 ;;
>                *)  file=$1 ;;
>        esac
>        shift
>done
>Anyway, when $1 is "-d", the test statement exits false, and the -d)
>line in the case statement is not executed.  Any arguments after this
>one are ignored by the while statement.  When I change the line in the
>case statemet to -b) , the script works as expected.

Test probably considers -d as an operator (directory check).
Use the following trick: test "X$1" != "X".

--

--    Bull Nederland NV, Product Support Unix, Amsterdam, The Netherlands

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by Jeff Beadl » Thu, 03 Dec 1992 23:34:19



>I'm trying to write a dinky sh script which contains the following
>while loop:
>while test "$1" != ""

...

Many versions of test have problems when doing string comparisions,
when the first argument starts with a '-'.  Change it to read:

while test "x$1" != "x"
...

        -Jeff
--

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by Uwe Waldma » Fri, 04 Dec 1992 01:06:50



Quote:(Karl Anderson) writes:
> I'm trying to write a dinky sh script which contains the following
> while loop:

> while test "$1" != ""
> do
>         case "$1" in
>                 -i) input=$2; shift ;;
>                 [+\-][0-9]*) version=$1 ;;
>                 -v) month=$2; day=$3; shift; shift ;;
>                 -d) del="yes" ; echo "XX" ;;
>                 -*) echo "get: unknown argument $1" 1>&2; exit 1 ;;
>                 *)  file=$1 ;;
>         esac
>         shift
> done

> The echo "XX" statement is only for debugging.

> Anyway, when $1 is "-d", the test statement exits false, and the -d)
> line in the case statement is not executed.  Any arguments after this
> one are ignored by the while statement.  When I change the line in the
> case statemet to -b) , the script works as expected.

First answer:  you probably want to check whether there are arguments
left, not, whether the first argument is the empty string.  So you
should use

  while test $# -ne 0

instead of

  while test "$1" != ""

Second answer:  Testing the equality of strings is a bit tricky.  If $1
equals "-d", then the shell expands

  while test "$1" != ""

to

  while test -d != ""

Now "test" sees "-d" (= "does directory exist?") and consequently checks
whether you have a directory called "!=".  Since you don't have such
a directory, the test fails.

The safe way to write a string comparison is to prepend some string that
is never interpreted by "test" to both arguments.  For example

  test "xxx$1" != 'xxx'

if you want to check whether $1 is not the empty string, or

  test "FOO$1" = "FOO$TEST"

if you want to check whether $1 equals $TEST.

--
Uwe Waldmann, Max-Planck-Institut fuer Informatik
Im Stadtwald, D-W6600 Saarbruecken 1, Germany

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by BRANDAUER CARL » Fri, 04 Dec 1992 01:23:46


Instead of resorting to various tricks, just use

        while test -n "$1"

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by Ulrich Steima » Fri, 04 Dec 1992 01:35:01



>I'm trying to write a dinky sh script which contains the following
>while loop:

>while test "$1" != ""
>do
>        something
>done

>Anyway, when $1 is "-d", the test statement exits false, and the -d)
>line in the case statement is not executed.
>What gives?

Simple. You do a "test -d != ''", that means, you're testing for the
directory '!=' - which isn't there. See the man page for test.

Just use
        while test x"$1" != x""
        do
                something
        done
and you will be happy.

Bye,
   UST
--
Ulrich STeimann, Quantum GmbH,    | Descartes enters a pub.
D-4600 Dortmund                   | "Evening, Descartes. Same as usual?"

Tel: +49-0231-75441-151, FAX -115 | -- and disappears.

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by Robert Hartm » Fri, 04 Dec 1992 02:44:56



>I'm trying to write a dinky sh script which contains the following
>while loop:

>while test "$1" != ""
>do
>        case "$1" in
>                -i) input=$2; shift ;;
>                [+\-][0-9]*) version=$1 ;;
>                -v) month=$2; day=$3; shift; shift ;;
>                -d) del="yes" ; echo "XX" ;;
>                -*) echo "get: unknown argument $1" 1>&2; exit 1 ;;
>                *)  file=$1 ;;
>        esac
>        shift
>done

>The echo "XX" statement is only for debugging.

>Anyway, when $1 is "-d", the test statement exits false, and the -d)
>line in the case statement is not executed.  Any arguments after this
>one are ignored by the while statement.  When I change the line in the
>case statemet to -b) , the script works as expected.

>What gives?

>k

It looks as though you're getting some interaction with test.  I
suspect that both -d and -b are being passed as options to test.
Why test doesn't barf on -b, I don't know; it looks to me like
neither should work.

In any case, when you're processing every word on the command line,
it's better to test the count of arguments being greater than 0:

while [ $# -gt 0 ] ; do
        case $1 in
        ...
        esac
        shift
done

Also, if you're going to be processing options that have their own
arguments, it's better to bite the bullet and use getopts(1) if you
have it, or getopt(1) if you don't.  Wierd cases come up when a
command requires that an option's argument take the form of a
suffix.  SCCS commands do that.  So what getopts (or getopt) pulls
apart, you sometimes have to put back together:

while getopts abo: c
do
        case $c in
        a | b)    opts="$opts -$c" ;;
        o)        opts="$opts -${c}${OPTARG}" ;;
        \?)       echo $usage
        esac
done
shift `expr $OPTIND - 1`

The "o" case sticks the option and argument back together.

-r

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by Bob Stockl » Fri, 04 Dec 1992 07:35:14



>I'm trying to write a dinky sh script which contains the following
>while loop:
>while test "$1" != ""
>do
>        case "$1" in
>                -i) input=$2; shift ;;
>                [+\-][0-9]*) version=$1 ;;
>                -v) month=$2; day=$3; shift; shift ;;
>                -d) del="yes" ; echo "XX" ;;
>                -*) echo "get: unknown argument $1" 1>&2; exit 1 ;;
>                *)  file=$1 ;;
>        esac
>        shift
>done
>Anyway, when $1 is "-d", the test statement exits false, and the -d)
>line in the case statement is not executed.  Any arguments after this
>one are ignored by the while statement.  When I change the line in the
>case statemet to -b) , the script works as expected.

In my "/bin/sh" as came with SCO Xenix386 v2.3.4, your script works as I
think you want it to ("script -d" prints "XX").

It may be that your shell sees the "test -d ..." as a test for what follows
to be a file that exists and is a directory.  You could prevent this (if it
is the case) by adopting a convention often used to obviate having to quote
(possibly null) strings in a "test", by prepending a character to the values
being compared:

        while test x$1 != x""

Or you might substitute:

        while test -n "$1"    or      while test $# -ne 0

Or, you might investigate the shell builtin "getopts" (if your shell has
it) or the UNIX program "getopt" (if your system has it), which are meant
to ease/standardize handling arguments given to shell scripts.  They have
the advantage of allowing a switch/flag followed by an argument to given
either with or without intervening whitespace with equivalent effect.

--

--

 
 
 

sh says: test "$1" = "" when $1="-b"

Post by DW » Sat, 05 Dec 1992 16:04:57



| while test "$1" != ""
| do
|         case "$1" in
|                 -i) input=$2; shift ;;
|                 [+\-][0-9]*) version=$1 ;;
|                 -v) month=$2; day=$3; shift; shift ;;
|                 -d) del="yes" ; echo "XX" ;;
|                 -*) echo "get: unknown argument $1" 1>&2; exit 1 ;;
|                 *)  file=$1 ;;
|         esac
|         shift
| done

| Anyway, when $1 is "-d", the test statement exits false, and the -d)
| line in the case statement is not executed.  Any arguments after this
| one are ignored by the while statement.  When I change the line in the
| case statemet to -b) , the script works as expected.

test understands "-d" as one of its own operator.  test -d != "" looks like
"while there exists a directory named !=" and the trailing "" is ignored; or
perhaps something similar happens.  At any rate, -d is a standard test
operator whereas -v, -i, and -b are not.

Some versions of test allow a - or -- option to make sure that all the rest
of the command line arguments are taken as strings.  This is surer, though:

while test Z"$1" != "Z"
do
        [your case structure, unchanged]
        shift
done

David W. Tamkin   Box 59297   Northtown Station, Illinois  60659-0297