2015-09-28 35 views
0

我正在考慮創建一個可以返回我們當前運行的終端類型的寶石,不管是Ubuntugnome terminal還是WindowCommand Processor。在這個問題中,我們稱這個gem爲「標識符」。確定一個特定的過程

我希望能夠做到這一點。

WindowCommand Procesor

> irb 
require 'identifier' 
Identifier.identify #=> 'Command Processor' 

UbuntuGnome Terminal

$ irb 
require 'identifier' 
Identifier.identify #=> 'Gnome Terminal' 

首先,我很想知道你有沒有發現這方面的信息的一個聰明的辦法。請記住,它在工作:

  • Windows 2000或更高
  • 的Linux 2.6+
  • FreeBSD的
  • 的Solaris 8+
  • HP-UX 10+
  • OS X 10.4+
  • AIX 5.3+

我想到的方式這樣做很簡單。首先,我用這段純紅寶石確定os:RbConfig::CONFIG['host_os']然後,我利用sys-proctable gem來獲取所有正在運行的進程的數組。然後我簡單地檢查這個進程數組是否包含可用於檢測到的操作系統的終端程序。這不會很聰明,我只需要對Windows,Linux,FreeBSD,Solaris,HP-UX,OS X和AIX的每個可用終端進行硬編碼,但仍然可行。這是一個有限的列表。如果某人的終端不能被定義,那並不重要。它會提出一個錯誤清楚地解釋問題,並鏈接到gem的github項目目錄,在這裏他們可以將終端名稱的過程名稱添加到項目中。反正,我的想法看起來是這樣的(僞代碼):

proc_table = Sys::ProcTable.ps 
case RbConfig::CONFIG['host_os'] 
when "i686-linux" 
    utilized = proc_table & ['terminator','tilda','guake','gnome-terminal','Yakuake','ROXTerm'] 
when "x64-mingw32" 
    utilized = proc_table & ['windows-command-host'] 
when "some-other-madness" 
... 
end 

現在,這實際上應該在大多數情況下工作,但有是竊聽我一個邊緣的情況下! 如果他們有兩個終端程序同時運行會怎麼樣?例如,如果gnome-terminal和ROXTerm都安裝並正在運行?

我們的utilized變量應該是這樣的:['gnome-terminal','ROXTerm']我們如何挑選哪一個?下面是一個問題......您是否有一種巧妙的方式,我們可以以某種方式操縱流程,以確定哪個流程是當前運行腳本的終端?或者其他的東西?如果這個問題沒有得到任何答案,我只會告訴用戶簡單地退出他們沒有使用的終端,但我希望能夠自動工作,我覺得這是可能的。該腳本已經從終端A執行,終端A和終端B都在運行......所以選擇終端A!似乎並不瘋狂。

任何想法?請記住,我們正在確定操作系統,以便操作系統特定的黑客可以接受

Related

+0

你不需要知道。你有環境變量TERM和terminfo數據庫,這應該足以滿足任何實際的原因。 –

+0

@ZsigmondLőrinczyENV [「TERM」]在所有非Linux操作系統中返回nil'。解釋如何獲取有關terminfo的這些信息。你的意思是這個寶石? http://www.a-k-r.org/ruby-terminfo/這只是返回一個終端的屏幕尺寸。沒有任何關於終端類型。我需要知道由於SGR依賴。 – JayTarka

+0

* SGR差異 – JayTarka

回答

2

怎麼樣建立一個進程樹的一個分支,以確定終端?

require 'sys/proctable' 

def process_tree_branch pid = Process.pid 
    proc_table = Sys::ProcTable.ps 
    by_pid = proc_table.inject({}) do |r, p| r[p.pid] = p; r; end 

    result = [] 

    current = by_pid[pid] 
    while current && current.pid != 0 do 
    result << current 
    current = by_pid[current.ppid] 
    end 

    result 
end 

puts process_tree_branch.map(&:cmdline).inspect 

# ["ruby example.rb", "-bash", "sshd: [email protected]/0", "sshd: vb [priv]", "/usr/sbin/sshd -D", "/sbin/init"] 
+0

看起來很有前途!你能解釋一下'inject'行嗎?另外,你的終端似乎沒有出現在你的示例數組中?對我來說,'2'索引返回'gnome-terminal',但是你是'sshd:vb @ pts/0'?我認爲不同的操作系統'會創建一個不同的進程樹,並且終端名稱/ exe將處於不同的索引處,但是你的任何東西都不像我的終端...我對操作系統知之甚少',你能解釋一下嗎? – JayTarka

+2

注入構建一個散列數組,其中pid是鍵,進程和結構是值。我的例子是在一些vps上遠程運行的,終端進程根本不存在(所以腳本遠程運行並且終端是本地的),但是對於任何具有ui的本地終端,它都可以正常工作,因爲終端通常是父節點正在運行的過程。這裏是我的macbook的例子:[「ruby example.rb」,「-bash」,nil,「/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal」,無]。我還修改了源代碼來處理內核任務,這些任務是其本身的父項。 –

+0

啊是的,我現在看到...嗯在Windows中,樹又是不同的......它在'1'索引:'「\」C:\\ Windows \\ System32 \\ cmd.exe \「/ E:ON/KC:\\ Ruby22-x64 \\ bin \\ setrbv ars.bat「'...我甚至無法簡單地掃描數組以找到可能的'exe',因爲在Windows中,Explorer.exe處於數組也是如此!你有興趣進行一點合作嗎?我認爲所有這些寶石需要的是一些以操作系統爲中心的邏輯深入到終端進程:) https://github.com/jaytarka/terminology/blob/develop/lib/terminology/utils.rb – JayTarka

相關問題