2011-07-15 81 views
5

簡單腳本這裏:BASH:用於從兩個輸入讀取最佳架構流

一個)從插座和存儲值的關聯數組不斷讀
b)中不斷從stdin讀取值和響應如果它們已經存在於關聯數組中,則爲t/f

a & b是隨機事件,不以任何方式關聯。

訣竅是從子進程都訪問數組(因爲把一個進程在後臺派生它作爲一個子進程)

我想通過最好的策略,併產生一些想法,但我不知道任何人有任何記好:

1)從套接字的輸入重定向到標準輸入作爲子進程,並在一個處理兩個輸入while循環(數據大小小,< 30個字符,所以我想他們會保持原子?)。
2)讀取套接字,然後在讀取時使用小(0.1?)超時值的STDIN,以模仿非阻塞I/O。
3)更新:將套接字數據寫入文件(實際上有另一個進程直接寫入文件),然後每次請求進來檢查值是否存在,處理文件中的條目,將它們添加到數組(使用文件鎖定)。

+0

聽起來像你有正確的想法。有沒有理由用bash來做而不是另一種語言? – Slartibartfast

+0

好問題。不,沒有理由對其他語言使用bash。 Bash是簡單而小巧的,這是唯一的原因(我有5個其他的bash腳本執行類似的認證/日誌記錄/用戶管理任務,所以很高興維護一個統一的平臺) –

回答

4

Bash不是這個的正確工具。通常使用select(2)poll(2)系統調用來解決此問題,它允許您在不旋轉的情況下同時等待多個文件描述符。 Bash沒有任何一個接口。

我推薦使用Python或Perl(實際上你很舒服)的腳本語言,它提供了與selectpoll(例如Python的select模塊)的接口。

+0

感謝您爲我設置直接。你是對的。在深入研究這個之後,作爲一個java小夥子,我會選擇合適的技術,並且盡力在groovy中完成這項任務。它已經在我的願望清單上了解了一段時間。 –

2

不知道在描述的上下文中這是否完全實用且足夠原子化,但使用客戶端/服務器模型和命名管道可以創建一個while循環來區分來自fifo或stdin

服務器不斷從套接字(/tmp/to)以及從stdin(它正在通過/tmp/to重定向到服務器)的行中讀取行。

但是,從stdin開始的行會被del字節(\177)標記爲該行的第一個字節。

然後,(後臺)客戶端while循環使用此第一個字節的行來區分不同來源的行。

# terminal window 1 

# server 
(
rm -f /tmp/to /tmp/from 
mkfifo /tmp/to /tmp/from 
while true; do 
    while IFS="" read -r -d $'\n' line; do 
    printf '%s\n' "${line}" 
    done </tmp/to >/tmp/from & 
    bgpid=$! 
    exec 3>/tmp/to 
    exec 4</tmp/from 
    trap "kill -TERM $bgpid; exit" 0 1 2 3 13 15 
    wait "$bgpid" 
    echo "restarting..." 
done 
) & 
serverpid=$! 

# client 
(
exec 3>/tmp/to; 
exec 4</tmp/from; 
while IFS="" read -r -d $'\n' <&4 line; do 
    if [[ "${line:0:1}" == $'\177' ]]; then 
    printf 'line from stdin: %s\n' "${line:1}" 
    else  
    printf 'line from fifo: %s\n' "$line" 
    fi 
done & 
trap "kill -TERM $"'!; exit' 1 2 3 13 15 
while IFS="" read -r -d $'\n' line; do 
    # can we make it atomic? 
    # sleep 0.5 
    # dd if=/tmp/to iflag=nonblock of=/dev/null # flush fifo 
    printf '\177%s\n' "${line}" 
done >&3 
) 
#kill -TERM $serverpid 


# terminal window 2 
echo hello > /tmp/to