无法在BASH脚本中建立Oracle SQL会话

问题描述:

#!/bin/bash 
#Oracle DB Info for NEXT 
HOST="1.2.3.4" 
PORT="5678" 
SERVICE="MYDB" 
DB_USER=$(whoami) 
DB_PASS=$(base64 -d ~/.passwd) 
DB_SCHEMA="my_db" 

#Section for all of our functions. 
function SQLConnection(){ 
sqlplus "$DB_USER"/"$DB_PASS"@"$HOST":"$PORT"/"$SERVICE" 
} 

function Connected(){ 
SQLConnection <<EOF 
select sys_context('USERENV','SERVER_HOST') from dual; 
EOF 
} 

function GetJMS(){ 
SQLConnection <<EOF 
set echo on timing on lines 200 pages 100 
select pd.destination from ${DB_SCHEMA}.pd_notification pd where pd.org_id = '$ORGID'; 
EOF 
} 
TODAY=$(date +"%A %B %d, %Y") 
read -r -p $'\n\nWhat is the ORG ID? ' ORGID 
read -r -p $'\n\nWhat is the REMOTE QUEUE MANAGER NAME? ' RQM 
read -r -p $'\n\nWhat is the IP address of the REMOTE QUEUE MANAGER? ' CONN 
read -r -p $'\n\nWhat is the PORT of the REMOTE QUEUE MANAGER? ' PORT 
echo -en "* $(whoami)\n* $TODAY\n* MQ Setup $ORGID\n\nDEFINE +\n\tCHANNEL('$RQM.LQML') +\n\tCHLTYPE(SDR) +\n\tCONNAME('$CONN($PORT)') +\n\tXMITQ('BUF.2.$ORGID.XMQ')\n\tCHAUTH(TLS_RSA_WITH_AES_256_CBC_SHA256)\n\nDEFINE +\n\tCHANNEL('LQML.$RQM') +\n\tCHLTYPE(RCVR) +\n\tTRPTYPE(TCP)\n\nDEFINE +\n\tQLOCAL('$RQM') +\n\tTRIGDATA('LQML.$RQM') +\n\tINITQ('SYSTEM.CHANNEL.INITQ') +\n\tTRIGGER USAGE(XMITQ)\n\n" > ~/mqsetup.mqsc 

CONNECTED=$(Connected | awk 'NR==16') 
echo -en "\n\nHello From: $CONNECTED\n\n" 

for JMSDESTINATION in $(GetJMS | awk 'NR>=16&&NR<=24{print $1}') 
    do 
     read -r -p $'\n\nWhich REMOTE QUEUE NAME matches with this ${JMSDESTINATION}?' RNAME 
     QDESC=$(echo "$JMSDESTINATION" | tr '.' ' ' | tr '[[:upper:]]' '[[:lower:]]') 
     echo -en "\n\nDEFINE +\n\tQR($JMSDESTINATION) +\n\t\tREPLACE DESCR('$ORGID $QDESC Queue') +\n\t\tREPLACE MAXDEPTH(5000) +\n\t\tXMITQ('BUF.2.$ORGID.XMQ') +\n\t\tRNAME('$RNAME') +\n\t\tRQMNAME('$RQM')" >> ~/mqsetup.mqsc 
    done 

以下是我构建的脚本,希望能够自动设置IBM MQ队列和通道。我的问题是,在这个脚本之外,我可以直接从shell中建立一个没有问题的SQL Session,只要我输入脚本中看到的变量即可。我可以调用这些函数,并且一切都会像我希望的那样返回。当我在脚本中运行完全相同的东西时,出现超时错误...“Hello From”为空,表示没有数据库连接。无法在BASH脚本中建立Oracle SQL会话

我完全难以理解,为什么它在脚本之外很好运行,但在它内部超时。

我很欣赏眼睛和帮助!

+1

连接部分似乎工作正常;如果您只是致电Connected,您会看到什么?你在哪里看到超时错误? (即使有连接,你的awk模式也不会显示任何东西,所以你可能想要做一些调试吗?) –

+0

难道你不需要在这一行中转义$符号:从$选择pd.destination {DB_SCHEMA} .pd_notification pd其中pd.org_id ='$ ORGID'; – BobC

+0

@AlexPoole是的,假设我已经直接将变量和函数加载到shell中,我可以调用函数“Connected”,并立即输出SQLPlus头文件,db-server主机名和所有退出信用。我使用AWK将其修剪为主机名。当我执行脚本并将所有内容加载到它的会话中时,脚本冻结就像尝试建立数据库连接一样,但它失败,因为我作为验证放入的echo语句失败,打印出“Hello From:”(空白处主机名将是)。 – misteralexander

您正在覆盖变量值。您在脚本的顶部有这样的:

PORT="5678" 

但后来你做的事:

read -r -p $'\n\nWhat is the PORT of the REMOTE QUEUE MANAGER? ' PORT 

这将覆盖5678值与任何输入的存在。该端口可能根本不在数据库服务器上进行监听,或者可能正在执行其他操作,或者如果您未输入值,则在连接时它将默认为端口1521。但是,无论哪种方式,连接都会失败,根据端口状态快速或慢速地进行连接(例如,如果防火墙阻止,连接速度可能会变慢)。

如果通过在read调用之前添加Connected调用来测试连接(正如我最初所做的那样),那么它似乎工作正常;但读取后的连接不起作用,因为它试图连接的端口值现在是错误的。

对两个变量使用不同的名称,例如, RQ_PORT第二个 - 在其read命令和随后创建~/mqsetup.mqsc文件。

您可能还会发现将-l标志添加到SQL * Plus调用中会很有用,因此如果连接由于某种原因而失败,它将不会再提示输入凭据,在某些情况下,该凭据可能会使脚本显示为直到你击中输入几次。


不直接相关的问题,但这样的事情自动化时,我平时也使用-s标志来抑制横幅(可环境之间会发生变化);如果你只对捕获查询输出感兴趣,我通常会将标题和/或分页设置为关闭和反馈关闭,并且通常将SQL * Plus设置为尽可能少地产生噪声 - 这使得解析出有趣的位更容易。

+0

这完全正确!天哪,我不敢相信我看起来就是那样!非常感谢你的支持。此外,不知道选项“-S”和“-L”......这些将有助于一吨。谢谢! – misteralexander