Jac*_*cob 18 shell oracle-database shell-script
使用以下 shell 脚本,为什么会出现错误
syntax error near unexpected token `else'
Run Code Online (Sandbox Code Playgroud)
外壳脚本
echo "please enter username"
read user_name
echo "please enter password"
read -s pass
echo ${ORACLE_SID}
SID=${ORACLE_SID}
if ["${ORACLE_SID}" != 'Test'] then
sqlplus -s -l $USER_NAME/$PASS@$SID <<EOF
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
EOF
else
echo "Cannot copy"
fi
Run Code Online (Sandbox Code Playgroud)
les*_*ana 32
你必须终止这样的条件if:
if [ "${ORACLE_SID}" != 'Test' ]; then
^ semicolon
Run Code Online (Sandbox Code Playgroud)
或者像这样:
if [ "${ORACLE_SID}" != 'Test' ]
then
^ newline
Run Code Online (Sandbox Code Playgroud)
注意:您还必须在 之后[和之前放置空格]。
;or换行的原因是if语句的条件部分只是一个命令。任何长度的任何命令,准确地说。shell 执行那个命令,检查命令的退出状态,然后决定是执行then部分还是else部分。
因为命令可以是任意长度,所以需要一个标记来标记条件部分的结束。那是;或 换行符,后跟then.
后面[有空格的原因是因为[是一个命令。通常是shell的内置。shell 执行命令[,其余部分作为参数,包括]作为强制的最后一个参数。如果你没有[在 shell后面放一个空格,它会尝试[whatever作为命令执行而失败。
之前空格的原因]是类似的。因为否则它不会被识别为它自己的参数。
您可以使用在线ShellCheck(也可作为独立工具提供)轻松检查您的 shell 脚本。
在这种情况下,它会指出 if 语句需要空格, after[和 before ],并且在同一行;之前需要一个(或换行符)then。
当你解决了这个问题后,它会继续告诉你它USER_NAME被使用而没有被初始化为任何东西。这是因为您还有一个user_name变量(大小写很重要)。PASS和也是如此pass。
它还告诉您使用read -rto stop readfrom mangling \(例如,对于密码可能很重要),并且您应该在调用时将变量双引号sqlplus以防止 shell 意外地进行文件名通配和分词(这同样很重要,如果例如,密码包含文件通配符,如*, 或空格)。
缩进代码也会使其更具可读性:
#!/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
Run Code Online (Sandbox Code Playgroud)
在这里,我还通过临时将IFS密码设置为空字符串来使用带有前导或尾随空格字符的密码read。
如果$ORACLE_SID/$sid是,则逻辑也已更改为退出Test。这避免了将脚本的主要操作部分放在if分支中。