shell采坑之旅--变量$PWD引发的血案
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell采坑之旅--变量$PWD引发的血案相关的知识,希望对你有一定的参考价值。
背景:
分组自研的数据库审计平台已在windows环境下,实现了一键拉取Oracle数据库性能报告的功能。
最近接到审计平台开发的小任务:将windows环境下实现一键拉取oracle数据库性能报告的bat脚本改为linux下的
shell脚本。
脚本改写的很快,三百多行的bat脚本,半天就改写成了shell,接下来就是最痛苦的测试环节了。
踩坑开始:
bat脚本在定义变量时,将连接数据库的密码定义为名为PWD的变量(如下),踩坑由此开始。。。
@echo off
...
set PWD=xxx
...
我在定义连接oracle的用户密码时,便参照bat脚本,仍使用PWD作为密码变量:
#################setting variables######################
。
。
TNS=dbname
PWD=pass1234
。
。
#################Making gather&scan Files######################
。
。
sqlplus dbaudit/[email protected]$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/[email protected]$TNS <<EOF >>sqlplus.log --第2部分
here is command2!
EOF
}&
done
wait
。
。
为了拉取oracle报告,在脚本中有多次连接数据库的操作:
sqlplus username/[email protected]$TNS <<EOF >>sqlplus.log
...
EOF
脚本看起来毫无破绽,可是执行时第1部分的sqlplus命令时,可以成功连接数据库,并执行相关操作;而执行到脚本第2部分的sqlplus命令时,却总是报sqlplus的语法错误!
这是为何呢?!
思来想去无果,百度是不可能有结果了,因为报错很直白,就是sqlplus语法不对。
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”的命令,难道是这个命令导致的?不应该呀!
继续将报错脚本拿出来单独执行,一次偶然的"echo $PWD"揭示了真相!
[[email protected] ~]$ echo $PWD
/paic/dba/tmp/padba
纳尼!PWD居然是linux系统自带的变量,而且显示的就是当前目录!
于是推断,在执行“cd $SHELL_PATH/$1”这样的change directory命令后,系统的PWD变量覆盖了脚本开始时
定义的PWD=pass1234,也就是说,在切换目录后,PWD的值就不是"pass1234"了,而是一个目录,也就是"$SHELL_PATH/$1"对应的值!
验证推断:
[[email protected] ~]$ export PWD=pass1234 --手动定义PWD变量
[[email protected] pass1234]$ echo $PWD
pass1234 --显示PWD变量值为pass1234,没毛病!
[[email protected] pass1234]$ cd --切换目录
[[email protected] ~]$ echo $PWD
/paic/dba/tmp/padba --PWD的值变为当前目录!
至此,真相大白!
修改脚本中的PWD为PASSWD后,报错消失,脚本顺利完成拉取报告的使命!
总结:
linux中有许多类似$PWD这类的变量,我们在脚本中定义变量名时,要避开系统自带的变量名,否则会导致灰常奇怪且让人欲罢不能的ERROR!
以上是关于shell采坑之旅--变量$PWD引发的血案的主要内容,如果未能解决你的问题,请参考以下文章