背景:
分组自研的数据库审计平台已在windows环境下,实现了一键拉取Oracle数据库性能报告的功能。
最近接到审计平台开发的小任务:将windows环境下实现一键拉取oracle数据库性能报告的bat脚本改成linux下的
shell脚本。
脚本改写的很快,三百多行的bat脚本,半天就改写成了shell,接下来就是最痛苦的测试环节了。linux
踩坑开始:
bat脚本在定义变量时,将链接数据库的密码定义为名为PWD的变量(以下),踩坑由此开始。。。sql
@echo off ... set PWD=xxx ...
我在定义链接oracle的用户密码时,便参照bat脚本,仍使用PWD做为密码变量:shell
#################setting variables###################### 。 。 TNS=dbname PWD=pass1234 。 。 #################Making gather&scan Files###################### 。 。 sqlplus dbaudit/$PWD@$TNS <<EOF >>sqlplus.log --第1部分 here is command1! EOF 。 。 #################Spooling Reports###################### cd $SHELL_PATH/$1 echo -e "Spooling Reports..." for(( i = 0; i < 10; i++ )) do { sqlplus dbaudit/$PWD@$TNS <<EOF >>sqlplus.log --第2部分 here is command2! EOF }& done wait 。 。
为了拉取oracle报告,在脚本中有屡次链接数据库的操做:数据库
sqlplus username/$PWD@$TNS <<EOF >>sqlplus.log ... EOF
脚本看起来毫无破绽,但是执行时第1部分的sqlplus命令时,能够成功链接数据库,并执行相关操做;而执行到脚本第2部分的sqlplus命令时,却老是报sqlplus的语法错误!
这是为什么呢?!
思来想去无果,百度是不可能有结果了,由于报错很直白,就是sqlplus语法不对。windows
Spooling Reports... SQL*Plus: Release 11.2.0.1.0 Production on Thu May 17 12:28:13 2018 Copyright (c) 1982, 2009, Oracle. All rights reserved. SQL*Plus: Release 11.2.0.1.0 Production Copyright (c) 1982, 2009, Oracle. All rights reserved. Use SQL*Plus to execute SQL, PL/SQL and SQL*Plus statements. Usage 1: sqlplus -H | -V -H Displays the SQL*Plus version and the usage help. -V Displays the SQL*Plus version. Usage 2: sqlplus [ [<option>] [{logon | /nolog}] [<start>] ]
因而,将变量部分和报错部分的脚本提取出,写在test.sh中单独执行,邪门的事情发生了,执行过程很成功!
奇怪了,脚本先后一样的命令,前面的成功,后面的失败了,why?!
仔细阅读脚本,中间只有一次“cd $SHELL_PATH/$1”的命令,难道是这个命令致使的?不该该呀!oracle
继续将报错脚本拿出来单独执行,一次偶然的"echo $PWD"揭示了真相!ide
[padba@cnsz081003 ~]$ echo $PWD /paic/dba/tmp/padba
纳尼!PWD竟然是linux系统自带的变量,并且显示的就是当前目录!性能
因而推断,在执行“cd $SHELL_PATH/$1”这样的change directory命令后,系统的PWD变量覆盖了脚本开始时
定义的PWD=pass1234,也就是说,在切换目录后,PWD的值就不是"pass1234"了,而是一个目录,也就是"$SHELL_PATH/$1"对应的值!测试
验证推断:code
[padba@cnsz081003 ~]$ export PWD=pass1234 --手动定义PWD变量 [padba@cnsz081003 pass1234]$ echo $PWD pass1234 --显示PWD变量值为pass1234,没毛病! [padba@cnsz081003 pass1234]$ cd --切换目录 [padba@cnsz081003 ~]$ echo $PWD /paic/dba/tmp/padba --PWD的值变为当前目录!
至此,真相大白!
修改脚本中的PWD为PASSWD后,报错消失,脚本顺利完成拉取报告的使命!
总结:
linux中有许多相似$PWD这类的变量,咱们在脚本中定义变量名时,要避开系统自带的变量名,不然会致使灰常奇怪且让人欲罢不能的ERROR!