
我目前正在開發一個插件來在我的文字編輯器中編譯 Oracle 程式碼。開發 SQL Developer 的人們最近新增了命令列版本sqlcl
。問題是,這是一個 Java 應用程式 -jvm
每次我需要進行編譯時啟動它 ( ) 的成本可能會很高 - 有一些報告稱它需要大約 20 秒。
我看到的一個建議是使用命名管道,如果我手動這樣做,似乎效果很好。
1號航廈:
mkfifo sqlconsole
tail -f sqlconsole | /opt/sqlcl/bin/sql /nolog
2 號航廈:
echo "conn hr/[email protected]/xe" > sqlconsole
且語句運行成功。
但問題是,在終端 2 中,我沒有從終端 1 獲得任何輸出(我想要的)。
..
我找到了這個文章關於從命名管道讀取輸出,但是即使這樣,輸出sqlcl
也不會被重定向(並且,在寫這篇文章時,似乎已經損壞了輸入)
#!/bin/bash
#consolereader.sh
trap "rm -f sqlconsole" EXIT
if [[ ! -p sqlconsole ]]; then
echo "pipe does not exist" >&2
exit 1
fi
while true
do
if read line < sqlconsole; then
if [[ "$line" == 'quit' ]]; then
break
fi
echo $line
fi
done
1號航廈:
mkfifo sqlconsole
tail -f sqlconsole | /opt/sqlcl/bin/sql /nolog
2 號航廈:
./consolereader.sh &
echo "conn hr/[email protected]/xe" > sqlconsole
我是否可以採取更好的方法 - 這樣我就可以sqlcl
在後台運行,並且仍然在我發送命令的會話中獲取輸出?
..
編輯:嘗試 Germar 的解決方案:
setUpPipes.sh(終端 1):
#!/bin/bash
rm -f sqlconsole
rm -f sqlconsole_out
mkfifo sqlconsole
mkfifo sqlconsole_out
tail -f sqlconsole | /opt/sqlcl/bin/sql /nolog | tee -a sqlconsole_out
編譯Oracle.sh(終端機2):
#!/bin/bash
echo "begin.."
tail -f /home/trent/pipedemo/sqlconsole_out &
echo "about to run connection"
echo "conn hr/[email protected]/xe" > /home/trent/pipedemo/sqlconsole
echo "select * from dual" > /home/trent/pipedemo/sqlconsole
echo "disconnect" > /home/trent/pipedemo/sqlconsole
echo "finished"
exit 0
答案1
您可以採取的一種方法是使用SPOOL
SQL 解釋器中的命令。
因此,像您已經這樣做的那樣啟動您的命名管道:
mkfifo sqlconsole
tail -f sqlconsole | /opt/sqlcl/bin/sql /nolog
接下來,建立 SQL 腳本,但這次啟用serveroutput
並假脫機到指定檔案。在這個例子中,我將這樣做out.txt
。
conn hr/[email protected]/xe
SPOOL out.txt
select * from dual;
set serveroutput on
exec dbms_output.put_line('PROCESS_FINISHED');
SPOOL OFF
disconnect
在這裡,我還選擇將字串列印到假脫機檔案 -PROCESS_FINISHED
作為腳本完成時標記的一種方式,因為 SQL 腳本和 bash 腳本將並行運行,bash 腳本可能會先完成腳本已經完成。
這樣,我就可以製作一個 bash 腳本 ( atomRunner.sh
) 將其發送到命名管道:
#!/bin/bash
> out.txt
cat connect.sql > sqlconsole
MAX_TIME=10
scriptStart=$(date -u +"%s")
secondsSince=0
while true; do
if [[ "${secondsSince}" -ge "${MAX_TIME}" ]] || grep -q "PROCESS_FINISHED" out.txt; then
break
fi
nowDate=$(date -u +"%s")
secondsSince=$((nowDate-scriptStart))
sleep 0.1
done
cat out.txt
if [[ "${secondsSince}" -ge "${MAX_TIME}" ]]; then
echo "Script took longer than expected to complete" >&2
exit 1
fi
exit 0
然後運行:
$ ./atomRunner.sh
SQL> set serveroutput on
SQL> select * from dual;
D
-
X
SQL> exec dbms_output.put_line('PROCESS_FINISHED')
PROCESS_FINISHED
SQL> SPOOL OFF