There are a few errors in this script. They all relate to command-line syntax, most for
bash, but in one case for the separate
expr utility. In summary:
- The original problem related to an unmatched
` in a backquote expression (and more generally, how to close a backquote expression and how newlines inside backquote expressions are handled by the shell).
- Other syntax errors preventing your script from working properly relate to argument parsing in the
[ construct and the
See below for details.
EOF in backquote substitution Error
As Florian Diesch says (and in Helio's answer also), the original problem was a missing
` at the end of the first backquoted
expr ... command. However, the more interesting aspect of this question is why do you get that error message? This is not merely a matter of idle curiosity--understanding that helps you comprehend this and other error messages in the future.
EOF stands for end-of-file and it means there are no more data available to read--in this case, text for the
bash interpreter to read. EOF is not inherently an error condition, but when an EOF is an error it usually means the interpreter thinks your program has ended prematurely--it was anticipating something, which never occurred in your program.
If the error message had said the error was an end of line in the backquote substitution, you would probably have immediately recognized the problem (provided you know that
` is called a backquote and and command substitution using a backquoted construct is also called backquote substitution).
bash think the file ends too soon, rather than the line? This is because you can actually have newlines (i.e., line breaks) inside a backquote expression:
ek@Io:~$ file `which vim
/usr/bin/vim: symbolic link to `/etc/alternatives/vim'
So what's happening is that bash reads the first backquote expression as
`expr $f\* $i
which is definitely not what you intended!
Then what you intended as the contents of the second backquote expression it sees outside of backquotes, and sees the following as a second backquote expression:
echo "The factorial of $num is $f"
echo "Enter positive number"
This is also not at all what you intended, and furthermore there is no closing backquote, which causes bash to report reaching end-of-file while still inside a backquote expression (
EOF in backquote substitution).
The solution is not to put a backquote at the very end of the script, of course! Instead, as others have said, simply add the missing backquote where it was supposed to be.
Note, however, that this must be
`, same as the opening backquote. Although the strange formatting displayed in the output of some command-line utilities might convey the impression that what begins with
` ends with
', that is not the case. (I noticed that had at one point written a
' rather than
` for the fix.)
[ Command: The
[: missing ] Error
After fixing the first problem, you got a
prog4: 5: [: missing ] error.
[ is a command (and in fact there is even a separate
[ executable, as unlike bash some shells don't provide a
[ builtin). Blank space must appear between it and its first argument.
Similarly, it is required to pass the closing
] of a
[ command as a separate command-line argument. That is, you must have blank space before the trailing
] as well as after the leading
if [ "$num" -ge 0]; then
should thus be rewritten to say:
if [ "$num" -ge 0 ]; then
For more details on
[ syntax, see the output of
help [ and
1 + 1
After fixing that problem, you'll get another error, which will look something like this (depending, perhaps, on what version of bash you are running):
bash: [: 1+1: integer expression expected
The problem is that
expr does not understand
1+1 is intended to mean "the sum of 1 and 1." It does not simplify it to
2, so the
[ command that subsequently examines it doesn't have an integer to evaluate.
Why doesn't the
expr utility know
1+1 is supposed to be interpreted as an integer, the sum of 1 and 1? This is because each number and arithmetic operator must be passed as a separate command-line argument to
ek@Io:~$ expr 1+1
ek@Io:~$ expr 1 + 1
To fix this problem, rewrite the line
to instead say:
i=`expr $i + 1`