shell采坑之旅--变量$PWD引起的血案

背景:
分组自研的数据库审计平台已在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!

相关文章
相关标签/搜索