
現在、テキスト エディターで 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
SPOOL
1 つの方法としては、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
ここでは、SQL スクリプトと bash スクリプトが並行して実行され、スクリプトが完了する前に bash スクリプトが完了する可能性が高いため、スクリプトが終了したことを示す方法として、スプール ファイルに文字列PROCESS_FINISHED
- - を出力することも選択しました。
これで、atomRunner.sh
名前付きパイプに送信する bash スクリプト ( ) を作成できます。
#!/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