3

Trying to run a bash script and while some things work correctly, I get this message:

line 34: unexpected EOF while looking for matching `)'

Here's the code, I've marked the line in question (in the hypotenuse method):

#!/bin/bash
# Bash Script Calculator
# -----------------------------------------------------
# 
# 
# 
# -----------------------------------------------------

a=$1
op="$2"
b=$3

if [ $# -lt 3 ]
then
    echo "$0 num1 opr num2"
    echo "Operators: +,-,x,/"
    exit 1
fi

case "$op" in
    +) echo $(( $a + $b ));;
    -) echo $(( $a - $b ));;
    x) echo $(( $a * $b ));;
    /) echo $(( $a / $b ));;
    hyp) hypotenuse;;
    area) area;;
    *) echo "Error: Not a listed operator"
       echo "If using multiplication, use "x"";;

esac

hypotenuse()
{
    hyp=$(bc -l << EOF     #LINE 34
    scale = 9
    sqrt ( $1 * $1 + $3 * $3 )
    EOF
    )   
    echo "$hyp"
}

area()
{
    area=$(echo "scale=2;3.14 * ($a * $a)" | bc)
    echo "$area"
}

Am I missing something? I've spent a little time looking things up on Google and such, nothing seems to tell me otherwise.

Thanks for any help!

CSRadical
  • 113
  • 1
  • 2
  • 7

1 Answers1

12

Your heredoc terminator is wrong:

{
    hyp=$(bc -l << EOF     #LINE 34
    scale = 9
    sqrt ( $1 * $1 + $3 * $3 )
    EOF
^^^^---these spaces count

Your terminator is now actually [space][space][space][space]EOF, while bash is looking for EOF WITHOUT the spaces. The terminator MUST begin at the start of the line, without any whitespace before (or after) it.

Since your heredoc never terminates, bash will run right off the end of the script looking for a ) which never comes, because the heredoc consumed the one you actually did have.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • 3
    It might be worth pointing out `<<-EOF` as an alternative (allowing tab-based, but not space-based, indentation at the heredoc's close). – Charles Duffy Aug 15 '14 at 16:15
  • @CharlesDuffy: That's a new one for me. Good tip. Thanks. – Marc B Aug 15 '14 at 16:16
  • 1
    Here is a shell stupidity. If you use <<-EOF, then the here doc's lines can be preceded by whitespace which is stripped away, and this is applied to the EOF also. But that whitespace has to be purely leading tabs! – Kaz Aug 15 '14 at 16:19
  • Thanks for both answers guys! Never would've thought that whitespace would account for anything, especially if it was tabbed properly for a method. – CSRadical Aug 15 '14 at 16:21
  • heredoc terminators are about the only time it would count. – Marc B Aug 15 '14 at 16:22
  • @CSRadical ...well, there are definitely plenty of places whitespace in general matters in shell -- `["$foo"="$bar"]` and `[ "$foo" = "$bar" ]` are entirely different things, after all -- but _leading_ whitespace... yeah, this is a fairly rare case. – Charles Duffy Aug 15 '14 at 16:45
  • @Kaz One purpose of the here document is to allow formatting (like leading whitespace) to be retained. Stripping all leading *tabs* (and only tabs) is simpler to implement than trying to strip a fixed number (say, 3) of spaces from each line and trying to deal with mixtures of spaces and tabs. – chepner Aug 15 '14 at 17:48