重定向命名管道中 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

編譯Oracle.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

您可以採取的一種方法是使用SPOOLSQL 解釋器中的命令。

因此,像您已經這樣做的那樣啟動您的命名管道:

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

相關內容