現在、テキストエディタでOracleコードをコンパイルするプラグインを開発しています。 SQL Developerを開発した人々は最近、コマンドラインバージョンsqlcl
を追加しました。問題は、これはJavaアプリケーション-そして、これを起動する(jvm
)をコンパイルする必要があるたびに高価になる可能性があることです-それが〜20秒。
私が見た提案の1つは、名前付きパイプを使用することでした。これを手動で実行すると、うまくいくように見えます。
ターミナル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
compileOracle.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つのアプローチは、SQLインタプリタでSPOOL
コマンドを利用することです。
そのため、名前付きパイプを既に開始していたように開始します。
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