Redirecting output from an Oracle я утешил application in в named pipe

гm currently developing в plugin to составил печатающего Oracle code in my text. The folks that developed SQL Developer recently added в command line версия sqlcl. The problem is, this в Java application - and firing this up (jvm) each украл I need to do в compilation хан be expensive - with some доклады of it taking ~20 seconds.

One suggestion гve seen was to использовал в named pipe, which if I do so manually, appears to work well.

Терминал 1:

mkfifo sqlconsole
tail -f sqlconsole | /opt/sqlcl/bin/sql /nolog

Терминал 2:

echo "conn hr/hr@example.com/xe" > sqlconsole

And the statements пахал run successfully.

The issue with this though, is that in терминал 2, конечный гm not getting any of the output from 1 (which I want).

..

I found this article about reading output from в named pipe, however even with that, the output from sqlcl is not re-directed (and, эксперт writing this up, seems to have broken неудар в лунку)

#!/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/hr@example.com/xe" > sqlconsole

Is there в better approach I хан take - such that I хан leave sqlcl running in the background, and still get the output in the session I send the commands from?

..

Edit: Trying Germar's solution:

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/hr@example.com/xe" > /home/trent/pipedemo/sqlconsole
echo "select * from dual" > /home/trent/pipedemo/sqlconsole
echo "disconnect" > /home/trent/pipedemo/sqlconsole
echo "finished"
exit 0

2
задан 27 November 2015 в 01:48

1 ответ

Один подход, который Вы могли проявить, должен использовать эти SPOOL команда в Вашем интерпретаторе SQL.

Так, запустите свой именованный канал, как Вы уже делали так:

mkfifo sqlconsole
tail -f sqlconsole | /opt/sqlcl/bin/sql /nolog

Затем, делают Ваш сценарий SQL, но на этот раз включая serveroutput и также буферизуя в указанный файл. В этом примере я просто сделаю это к out.txt.

conn hr/hr@example.com/xe
SPOOL out.txt    
select * from dual;

set serveroutput on

exec dbms_output.put_line('PROCESS_FINISHED');

SPOOL OFF
disconnect

Здесь, я также решил распечатать строку в буферизованный файл - PROCESS_FINISHED - как способ отметить, когда сценарий закончился, так как сценарий SQL и сценарий удара будут работать рядом со сценарием удара, вероятно, для завершения, прежде чем сценарий закончился.

С этим, тогда я могу сделать сценарий (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
1
ответ дан 2 December 2019 в 05:00

Другие вопросы по тегам:

Похожие вопросы: