2017-04-24 104 views
0

我有一個bash腳本包裝bash腳本調用KSH腳本,但掛在功能

foo.sh:

#!/bin/bash 
echo "start" 
. /path/to/bar/bar.ksh 
echo "after bar" 

getoravariables $1 

bar.ksh(目的是剛剛成立的Oracle變量):

#!/bin/ksh 
echo "b4 getora" 
getoravariables() { 
echo "1" 
if [ $# -ne 1 ] 
then 
echo "2" 
     echo "Usage: getoravariables sid" 
     exit 1 
fi 

grep -w ${1} ${ORATAB_LOC} | grep -v "#" | sed "s/:/ /g" | read SID ORAHOME ASK 


if [ $? -ne 0 ] 
then 
     print "Error: Please enter a vaild SID and check the ${orafile} file for correct input" 
     return 1 
fi 

ps -ef|grep pmon|grep ${SID} >> /dev/null 

if [ $? -ne 0 ] 
then 
     print "Error: SID ${SID} does not seem to be started. " 
     return 2 
fi 

export ORACLE_SID=${SID} 
export ORACLE_HOME="${ORAHOME}" 
export ORAENV_ASK=NO 

. $ORACLE_HOME/bin/oraenv > /dev/null 

} 
echo "after getora" 

執行foo.sh後我得到:

>./foo.sh validsid 
start 
b4 getora 
after getora 

所以我可以說,自從「b4 getora」和「getora之後」的echo命令工作以後,只需調用ksh腳本就沒有問題。但是執行該函數有一些問題,因爲我沒有得到我期望的回聲「1」或回聲「2」。此外,如果我運行foo.sh作爲ksh腳本,一切正常。

因此,我可以假設這兩種語言之間的語法存在某種差異,但我並不感興趣。任何人都可以協助

UPDATE: 我在全KSH腳本的頂部添加set -x,(我包含在我的問題只是一個子集)。我發現劇本中我的腳本功能我貼掛在一個點以後:

++ echo 

++ grep -v '#' 
++ read VAR VALUE 
(hanging here) 

對於這部分腳本那些代碼是:

echo $GLOBPARFIL 
grep -v "#" ${GLOBPARFIL}|while read VAR VALUE 
do 
     export ${VAR}=${VALUE} 
done 

所以$GLOBPARFIL不被設置正常。它也恰好是一個變量,從getoravariables()被拉入和設置。從調試達輸出說明了這一點:

++ read VAR VALUE 
++ export GLOBPARFIL=/home/local/par/global.par 
++ GLOBPARFIL=/home/local/par/global.par 

這行了@jlliagre回答以下聲明的變量沒有得到正確設置。不過,我嘗試瞭解決方法只有相同的不良結果。

更新2:

按照規定我能找到真正的源頭,並創建一個解決方法的信息和邏輯:

問題:

grep -v "#" ${file_location}| tr "^" " " | while read VAR VALUE 

SOLUTION:

while read VAR VALUE 

do 

     export ${VAR}=${VALUE} 
done <<% 
$(grep -v "#" ${file_location}| tr "^" " ") 
% 

我會馬上k一樣完整。但是,如果我可以收到更多關於爲什麼這種解決方法可以解決問題的信息,我將不勝感激。

回答

3

源文件忽略了shebang,所以它引用的事實ksh並不妨礙bash來處理它。

的問題是與該行:

grep -w ${1} ${ORATAB_LOC} | grep -v "#" | sed "s/:/ /g" | read SID ORAHOME ASK 

ksh,管道的最後一個組件是由主殼運行,而在bash下,它是由一個子shell中運行。然後在bash下設置變量SID,ORAHOMEASK

這裏是一個解決辦法:

read SID ORAHOME ASK <<% 
$(grep -w ${1} ${ORATAB_LOC} | grep -v "#" | sed "s/:/ /g") 
% 

編輯:

對於第二個問題,你可以使用:

while read VAR VALUE 
do 
     export ${VAR}=${VALUE} 
done <<% 
$(grep -v # "${GLOBPARFIL}") 
% 

如果GLOBPARFIL設置,變量會被正確地設置和導出,如果GLOBPARFIL未設置,這可能是一個問題,至少不會掛起腳本。

說明:

當您運行shell命令管道時,例如, command1 | command2 | command3bash解釋器正在子shell中運行每個命令。這意味着在其中一個管道命令中完成的任何變量設置都會丟失。在你的腳本中,你有幾個成語。這適用於ksh,它在當前shell中運行read指令,但不與bash一起運行。

便攜式解決方法是通過讀取行​​開頭的變量來顛倒命令的順序,並使用here document來設置讀取標準輸入。這裏的文檔由任何自定義字符串分隔,常見的是%。這裏的文檔通常包含標準輸入本身作爲純文本。在這裏,我們希望該輸入是流水線中的set指令之前的命令的結果,因此使用command substitution$(command))。這裏輸入command這裏的文件。

您可能還使用process substitution

read SID ORAHOME ASK < <(grep -w ${1} ${ORATAB_LOC} | grep -v "#" | sed "s/:/ /g") 

...

while read VAR VALUE 
do 
     export ${VAR}=${VALUE} 
done < <(grep -v "#" "${GLOBPARFIL}") 
+0

謝謝你,我的例子bar.ksh腳本實際上是我的一個更大腳本的子集。你的回答讓我質疑,如果我的真正酒吧。ksh正在一路走到最後。我在它的最後發出了回聲,它沒有回來。這個問題必須在其他地方,我將不得不更多地尋找來源。 –

+0

@ exit_1要調試shell腳本,請在開始處加上'set -x'。它會在執行它們時顯示所有行。 – Barmar

+0

是的,或者只是運行'bash -x foo.sh'。 – jlliagre

0

最有可能的情況是,函數名「getoravariables」來定義第二函數(沒有按在這裏沒有列出的其中一個腳本內部做任何可見的事情。 嘗試在所有文件中grep for「getoravariables」,也許你會找到它。

0

我有這樣的腳本來「強制」bash執行腳本。

#!/bin/sh 
# 

if [ "$(ps -p "$$" -o comm=)" != "bash" ]; then 
    exec /usr/local/bin/bash "$0" "[email protected]@" 
    exit 255 
fi 
echo blah... 

我假設你可以使用類似的東西強制執行ksh。 ps選項是POSIX,所以它們應該是便攜式的。

p.s.如果有更好的方法來做到這一點,請發佈。我並不自豪。