Shell Script - syntax error near unexpected token `else'
You have to terminate the condition of if
like this:
if [ "${ORACLE_SID}" != 'Test' ]; then
or like this:
if [ "${ORACLE_SID}" != 'Test' ]
then
Note: you also have to put spaces after [
and before ]
.
The reason for the ;
or linebreak is that the condition part of the if
statement is just a command. Any command of any length to be precise. The shell executes that command, examines the exit status of the command, and then decides whether to execute the then
part or the else
part.
Because the command can be of any length there needs to be a marker to mark the end of the condition part. That is the ;
or the newline, followed by then
.
The reason for the spaces after [
is because [
is a command. Usually a builtin of the shell. The shell executes the command [
with the rest as parameters, including the ]
as mandatory last parameter. If you do not put a space after [
the shell will try to execute [whatever
as command and fail.
The reason for space before the ]
is similar. Because otherwise it will not be recognized as a parameter of its own.
You may easily check your shell scripts using ShellCheck online (also available as a standalone tool).
In this case, it will point out that the if-statement needs spaces, after [
and before ]
, and that you need a ;
(or a newline) before the then
on the same line.
When you've fixed that, it will go on to tell you that USER_NAME
is used without being initialized to anything. This is because you also have a user_name
variable (case matters). The same is true for PASS
and pass
.
It also tells you to use read -r
to stop read
from mangling \
(could be important for passwords, for example), and that you should double quote the variables when calling sqlplus
to prevent the shell from accidentally doing file name globbing and word splitting (again this is important if the password, for example, contains file globbing characters like *
, or spaces).
Indenting the code will make it more readable too:
#!/bin/bash
read -r -p 'please enter username: ' user_name
IFS= read -rs -p 'please enter password: ' pass
printf 'ORACLE_SID = %s\n' "$ORACLE_SID"
sid=$ORACLE_SID
if [ "$sid" = 'Test' ]; then
echo 'Cannot copy' >&2
exit 1
fi
sqlplus -s -l "$user_name/$pass@$sid" <<'SQL_END'
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
SQL_END
Here I've also made it possible to use passwords with leading or trailing space characters by temporarily setting IFS
to an empty string for the password reading read
.
The logic was also changed to bail out if $ORACLE_SID
/$sid
is Test
. This avoids having the main operational part of the script in an if
branch.
When writing sh
you'd want
if [ "$ORACLE_SID" != "Test" ]
then
...
fi
When writing bash
if [[ "$ORACLE_SID" != "Test" ]]
then
...
fi
Mind the spaces please. There must be a space between [[
and first operator.