Nested ctrl statements syntax confusion

Nested ctrl statements syntax confusion

Post by Harry Putna » Fri, 15 Dec 2000 23:07:55



I get easily confused when nesting the various control constructs in
bash shell scripts.

Here we have an `while' inside an `if' inside a `case' inside a
`while'.
  (and the thigh bones connected to the knee bone...)

Probably should be easy to get the format right, but not for me. Not
all is shown here.  For breivity I've snipped a couple of `here
documents' and commments.  When I try to run this with the "-w" flag
and 3 args.    -w(1) "something"(2)  non-file(3)

(using a non-file name to test)

I get this error... :

line 71: syntax error near unexpected token `;'
line 71: `          done                      ;;    '

[I've rearranged the double colons the fis and the
dones many times and the error message changes accordingly,
but having a problem seeing my mistake]

I'd like some advice on how to debug this kind of problem easily.

Also a related syntactical question:  In the `if' clause I've
attempted to capture the argument count:
 ` cnt="$#"'
And presented it for a file test:
 if     [ -f "$($cnt)" ] ;then

Trying to determine if last arg is infact a file.
But not sure if this is how that would be done.

Pseudo script:
^^^^^^^^^^^^^^^^^^^^^^
[`Here docs' snipped [...] various usage statements]

What is wrong in this picture?

This script, with -w flag expects the user to insert data and hit ^d to write
it to the selected file.

    [ -z "$1" ] && {
       usage1
       exit 1
   }    
      while getopts "hHw:r:" opt; do
       case "$opt" in
        w) cnt="$#"
   ## wants to see if last arg is legit filename
        if      [ -f "$($cnt)" ] ;then
   ## save OPTARG for writing
           wdata=`echo "Something: $OPTARG"`
           shift
           echo "$wdata"         >>   $1
           date +"%b %d %T %Y"   >>   $1
           echo  "Hit ^d when done to write data to $2"

           while read line
               do
               echo $line        >>  $1            
           done                       ;;                

        else
           echo ""
           echo "WAIT...$cnt either doesn't exist or is not a regular file"
           echo "type \`$(basename $0) -h' for minimal usage statement"
           echo "type \`$(basename $0) -H' for maximum usage statement"
           echo ""
           exit 1                    
      fi
        r) awk '/^Keywords:.*'"$OPTARG"'/,/\&\&$/' $3 ;;      
        h) usage1                     ;;
        H) usage2                     ;;
        *)      usage1                     ;;

           esac
   done

 
 
 

Nested ctrl statements syntax confusion

Post by brian hile » Sat, 16 Dec 2000 05:42:28



> I get easily confused when nesting the various control constructs in
> bash shell scripts.
> Here we have an `while' inside an `if' inside a `case' inside a
> `while'.
>   (and the thigh bones connected to the knee bone...)
> Probably should be easy to get the format right, but not for me. Not
> all is shown here.  For breivity I've snipped a couple of `here
> documents' and commments.  When I try to run this with the "-w" flag
> and 3 args.    -w(1) "something"(2)  non-file(3)

> (using a non-file name to test)
> I get this error... :
> line 71: syntax error near unexpected token `;'
> line 71: `          done                      ;;    '
> [I've rearranged the double colons the fis and the
> dones many times and the error message changes accordingly,
> but having a problem seeing my mistake]
> I'd like some advice on how to debug this kind of problem easily.
> Also a related syntactical question:  In the `if' clause I've
> attempted to capture the argument count:
>  ` cnt="$#"'
> And presented it for a file test:
>  if        [ -f "$($cnt)" ] ;then
> Trying to determine if last arg is infact a file.
> But not sure if this is how that would be done.
> Pseudo script:
> ^^^^^^^^^^^^^^^^^^^^^^
> [`Here docs' snipped [...] various usage statements]
> What is wrong in this picture?
> This script, with -w flag expects the user to insert data and hit ^d to write
> it to the selected file.
>     [ -z "$1" ] && {
>        usage1
>        exit 1
>    }      
>       while getopts "hHw:r:" opt; do
>        case "$opt" in
>         w) cnt="$#"
>    ## wants to see if last arg is legit filename
>         if [ -f "$($cnt)" ] ;then
>    ## save OPTARG for writing
>            wdata=`echo "Something: $OPTARG"`
>            shift
>            echo "$wdata"         >>   $1
>            date +"%b %d %T %Y"   >>   $1
>            echo  "Hit ^d when done to write data to $2"

>            while read line
>                do
>                echo $line        >>  $1            
>            done                       ;;          

>         else
>            echo ""
>            echo "WAIT...$cnt either doesn't exist or is not a regular file"
>            echo "type \`$(basename $0) -h' for minimal usage statement"
>            echo "type \`$(basename $0) -H' for maximum usage statement"
>            echo ""
>            exit 1                    
>       fi
>         r) awk '/^Keywords:.*'"$OPTARG"'/,/\&\&$/' $3 ;;
>         h) usage1                     ;;
>         H) usage2                     ;;
>         *) usage1                     ;;

>            esac
>    done

The case pattern terminating ";;" doesn't go into the middle of
an embedded "while" statement, as "done ;;" above; it goes after
the "fi" and just before following case patterns: "fi ;;".

As for your second query, the shell parses variables expansion once
only; to make the test conditional work, change 'cnt="$#"' to "eval
lastfile=\${$#}" (double-quotes are not necessary.) Variable
"lastfile" will now contain the value of the last positional
parameter, which you may test on directly.

-Brian

 
 
 

Nested ctrl statements syntax confusion

Post by Harry Putna » Sat, 16 Dec 2000 07:30:06


[...]

Quote:> The case pattern terminating ";;" doesn't go into the middle of
> an embedded "while" statement, as "done ;;" above; it goes after
> the "fi" and just before following case patterns: "fi ;;".

Well put... he he... I had discovered exactly that with considerable
more fiddling before I saw your post... thanks.

Quote:> As for your second query, the shell parses variables expansion once
> only; to make the test conditional work, change 'cnt="$#"' to "eval
> lastfile=\${$#}" (double-quotes are not necessary.) Variable
> "lastfile" will now contain the value of the last positional
> parameter, which you may test on directly.


hold the same value at the end of the script as they do at the
beginning?

Before seeing your post, I'd altered the script quite a bit to solve
this and some other problems and ended up with this technique to set
up the file test:

     if [ -f "$last_arg" ] ;then
[...]
Which seems to work too.

Now working with your new information, and I'm always pleased to see
examples of the sometimes intricate escape/quoting some times
required, and the different usages of () and {}. Seems like quite a
lot to keep up with sometimes.

I'd probably never have hit on \${$#}

So trying your example like this:

  ## capture the value of the last command line arg
       w) "eval lastfile=\${$#}"

  ## Test to see if it is a legit file    
         if     [ -f "$lastfile"  ] ;then

Kicks out an error that can be seen in the "-x" flag output:

$ tasks2 -w "now" it

[...]

   + getopts hHw:r: opt
   + 'eval lastfile=${3}'
   /home/reader/scripts/tasks2: eval lastfile=${3}: command not found
   + '[' -f '' ']'

[...]

Am I missing a quote somewhere or maybe need to supply a `path' for
`eval'.

 
 
 

Nested ctrl statements syntax confusion

Post by Barry Margoli » Sun, 17 Dec 2000 09:24:00





>hold the same value at the end of the script as they do at the
>beginning?


shift moves $2 into $1, $3 into $2, and so on; getopts updates them to
remove the option parameters, and the "set" command can be used to replace
the whole parameter list.

--

Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

1. Lack of spaces in csh if statements cause nesting to fail.

In the following program

if($x == 1) then
        if($x == 2) then
                echo "aa"
        endif
        echo "bb"
endif

"bb" is printed to the screen. If a space is placed between the
if and the paren on the *second* if, nothing is printed. This
will fail in the same manner if y is set to 2.

A space in the first if has not affect.

No warnings are errors are given if the space is not in the
second if statement; it just works incorrectly.

Why is the space in the second if statement critical?
Why does it not give any error or warning?
And, what does it think is going on in the second if statement
if the space is missing?

Thanks for the help!

chris

****************************************************
*   Chris N. Hinds <><                             *

*   (512) 891-2753   FAX: (512) 891-3147           *
*                                                  *
*   Motorola Inc.                                  *
*   Microprocessor and Memory Technologies Group   *
*   Mail Drop OE32                                 *
*   6501 William Cannon Dr. West                   *
*   Austin, Tx 78735-8598                          *
****************************************************

2. Adding a new font on Solaris 2.6

3. nested case statement ??

4. Solaris 8 Jumpstart help please

5. nesting 'case' statements

6. 3Com 905TX not working, which module?

7. Syntax error in nested loop?

8. (Linux with Win95) ---> to the net with PPP question

9. LILO append statement syntax

10. Conditional statement syntax in a Makefile

11. syntax of if statement

12. syntax for an IF statement

13. LILO append statement syntax