2009-12-04 45 views
8

以UNIX-y方式,我試圖啓動一個進程併爲其啓動背景,並將該進程的生命週期與我的shell聯繫起來。我想說的不僅僅是後臺進程的背景,我希望進程發送SIGTERM,或者它有一個關閉的打開的文件描述符,或者當shell退出時,所以shell的用戶不必明確地終止進程或得到「你有運行作業」的警告。將進程的生命與啓動它的shell聯繫起來

最終我想要一個程序,它可以唯一地爲每個shell運行,並隨該shell運行狀態,並在shell關閉時關閉。

IBM的DB2控制檯命令以這種方式工作。當連接到數據庫時,它會產生一個「db2bp」進程,該進程承載數據庫狀態和連接並將其綁定到您的shell。您可以連接多個不同的終端或ssh連接,每個連接都有其自己的db2bp進程,並且當這些進程關閉時,相應的db2bp進程將死亡,並且該連接將關閉。

DB2查詢然後通過db2命令啓動,db2命令只是將它轉交給相應的db2bp進程。我不知道它是如何與正確 db2bp進程進行通信,但也許它使用連接到stdin的tty設備作爲唯一密鑰?我想我也需要弄清楚。

我從來沒有寫過任何tty操作,所以我不知道哪裏可以開始。如果我能產生一個在shell退出時自動終止的進程,我想我可以計算出其餘部分。任何人都知道DB2是如何做到的?

回答

2

如果您的shell不是子shell,您可以執行以下操作;把下列句子變成一個名爲「ttywatch」腳本:

#!/usr/bin/perl 
my $p=open(PI, "-|") || exec @ARGV; sleep 5 while(-t); kill 15,$p; 

然後運行您的程序爲:

$ ttywatch commandline... & disown 

Disowning的過程中會阻止shell抱怨有正在運行的進程,並在終端關閉時,會在5秒內將SIGTERM(15)傳送到子流程(您的應用程序)。

如果shell不是子shell,你可以使用像ttywrap這樣的程序至少給它自己的tty,然後上面的技巧就可以工作。

+0

是的,這是有效的!我想出了db2如何做,這不完全相同,但這是如此簡短。我的perl並不是那麼偉大,雖然...什麼是(-t)測試? – Kyren 2009-12-04 21:14:43

+0

啊,找到了。 -t默認爲標準輸入,並測試以查看文件是否打開到tty ...非常漂亮。 – Kyren 2009-12-04 21:21:52

0

當它關閉時,你的shell應該發送一個SIGHUP信號給正在運行的子進程。你有沒有嘗試在應用程序中添加一個SIGHUP處理程序,以便在shell退出時乾淨地關閉它 ?

+0

我剛剛嘗試過,但我不認爲它的作品。 如果背景這條巨蟒過程: 進口操作系統,SYS,時間,信號 高清處理器(正負號,車架): 打印 '退出補時信號後',正負號sys.exit(0) 信號。信號(signal.SIGHUP,處理器) while True: time.sleep(1) 然後shell仍然抱怨退出時運行的作業(或者,如果配置爲只是讓進程永遠運行)。這個過程似乎沒有發送SIGHUP直到我殺死-SIGHUP它。 – Kyren 2009-12-04 19:09:58

+0

哇,我真的在堆棧溢出格式化失敗。 – Kyren 2009-12-04 19:10:31

0

這有可能是你真正的問題是殼而不是你的過程。我的理解同意吉姆劉易斯的說法,即殼在死後應該得到SIGHUP。但是你所抱怨的是shell(或者終端)試圖阻止你意外地使用活躍的孩子殺死一個正在運行的shell。

請考慮閱讀shell或終端的手冊以查看此行爲是否可配置。

從我的MacBook bash的手冊:

shell退出通過在收到SIGHUP的默認。在退出之前,交互式shell會將SIGHUP 重新發送到正在運行或已停止的所有作業。停止的工作發送SIGCONT以確保他們收到SIGHUP。若要阻止shell將信號發送到特定作業,應將其從作業表中刪除(請參見下面的SHELL BUILTIN COMMANDS)或使用disown -h標記爲不接收SIGHUP。

如果已使用shopt設置huponexit shell選項,則當交互式登錄shell退出時,bash將向所有作業發送SIGHUP。

這可能會指出你在正確的方向。

+0

這是,但我不應該這樣做。我沒有看過,但我確實在bash和zsh手冊中找到了這個選項。儘管如此,我不應該*有*這樣做。是的,我可以配置bash或zsh,以便在所有後臺進程退出時終止它們,儘管manpages表明不這樣做,但DB2似乎並不需要,現在它可以正常工作。 DB2如何做到這一點? – Kyren 2009-12-04 19:13:12

+0

'fraid我幫不了那麼多。我同意這是一個理想的功能,只是不知道該怎麼做。 – dmckee 2009-12-04 19:24:44

+0

好,爲了糾正我自己,他們沒有被殺 - 就像你說的,他們正在SIGHUP-ed :)而且,它只是zsh手冊頁,暗示總是使用NO_CHECK_JOBS和NO_HUP。但仍然,我不應該重新配置我的外殼 – Kyren 2009-12-04 19:25:03

2

好吧,我想我想通了。我讓它太複雜了:)

我認爲所有的db2都是守護進程db2bp,然後db2bp在父PID(shell的PID)上調用waitpid並在waitpid返回後退出。

db2命令和db2bp之間的通信似乎是通過fifo完成的,其文件名基於父shell的PID。

Waaaay簡單,比我想:)

對於任何人誰是好奇,這所有的努力是能夠扎一個Python或Groovy交互式會話的外殼,這樣我就可以測試代碼,而很容易地在跳並退出會保留數據庫連接和臨時類/變量的會話。

謝謝大家的幫助!

相關問題