shell采坑之旅--變量$PWD引發的血案
阿新 • • 發佈:2018-05-17
shell linux oracle 背景:
分組自研的數據庫審計平臺已在windows環境下,實現了一鍵拉取Oracle數據庫性能報告的功能。
最近接到審計平臺開發的小任務:將windows環境下實現一鍵拉取oracle數據庫性能報告的bat腳本改為linux下的
shell腳本。
腳本改寫的很快,三百多行的bat腳本,半天就改寫成了shell,接下來就是最痛苦的測試環節了。 定義的PWD=pass1234,也就是說,在切換目錄後,PWD的值就不是"pass1234"了,而是一個目錄,也就是"$SHELL_PATH/$1"對應的值!
分組自研的數據庫審計平臺已在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/$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語法不對。
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"揭示了真相!
[padba@cnsz081003 ~]$ echo $PWD
/paic/dba/tmp/padba
納尼!PWD居然是linux系統自帶的變量,而且顯示的就是當前目錄!
於是推斷,在執行“cd $SHELL_PATH/$1”這樣的change directory命令後,系統的PWD變量覆蓋了腳本開始時
驗證推斷:
[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!
shell采坑之旅--變量$PWD引發的血案