Oracle コンソール アプリケーションからの出力を名前付きパイプにリダイレクトする

Oracle コンソール アプリケーションからの出力を名前付きパイプにリダイレクトする

現在、テキスト エディターで 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

SPOOL1 つの方法としては、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

関連情報