명명된 파이프에서 Oracle 콘솔 애플리케이션의 출력 리디렉션

명명된 파이프에서 Oracle 콘솔 애플리케이션의 출력 리디렉션

저는 현재 텍스트 편집기에서 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

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취할 수 있는 한 가지 접근 방식은 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

관련 정보