Shell
編寫器程序退出後如何從命名管道中讀取?
我想將命名管道用作非同步任務隊列(可能類似於 JMS)。
例如,假設客戶端發送了一些我希望插入數據庫的數據,但我希望客戶端立即斷開與伺服器的連接,並且伺服器程序將數據通過管道傳輸到命名管道。然後完全獨立地從管道中讀取數據並執行 SQL 插入,這可能非常慢 - 但客戶端不會注意到,因為它會立即得到響應。
作為原型,我認為這會起作用(為簡單起見,回顯“45”而不是通過 netcat 客戶端-伺服器對發送):
zsh> nohup echo "45" > my_named_pipe & zsh> exit zsh: warning: 1 jobs SIGHUPed
然後很久以後,執行
zsh> cat my_named_pipe
但是沒有任何東西從管道中流出。我的設置有什麼問題?
PS:我從來沒有
nohup
工作過。在這種情況下,我總是依賴disown
我不想做的單獨命令。
當你這樣做時:
nohup echo "45" > my_named_pipe &
外殼會自行分叉。在孩子身上,它開始
my_named_pipe
寫作。這open()
會阻塞,直到有其他內容my_named_pipe
可供閱讀。當您
exit
在父程序中執行時,子程序仍然被阻塞open()
並且尚未執行nohup
。因此,在退出 shell 時,shell 會將 SIGHUP 發送給孩子,它不會忽略它,因為它還沒有執行
nohup
。趕緊跑:
(echo 45 > my_named_pipe &)
或與
zsh
:echo 45 > my_named_pipe &!
&!
是 zsh 的語法糖嗎disown
BASH 和 ZSH 都有一個很好的內置函式,稱為 disown。它使使用者能夠以與 nohup 非常相似的方式從 shell 中分離程序。ZSH 有一個很好的糖:你可以放 &!在命令結束時,它將被分離。BASH 沒有這種糖
http://blog.debiania.in.ua/posts/2013-03-13-fun-with-bash-disown.html