我想创建一个可以返回我们当前正在运行的终端类型的gem,无论是Ubuntu
&#39} gnome terminal
还是{{1} {' s Window
。让我们称这个宝石为#34;标识符"在这个问题上。
我希望能够做到这一点。
在Command Processor
' Window
:
Command Procesor
在> irb
require 'identifier'
Identifier.identify #=> 'Command Processor'
' Ubuntu
:
Gnome Terminal
首先,我很想知道您是否有一种聪明的方法来查找这些信息。请记住,它必须在:
我想这样做的方式非常简单。首先,我使用这个纯ruby片段确定操作系统:$ irb
require 'identifier'
Identifier.identify #=> 'Gnome Terminal'
然后,我利用sys-proctable gem获取所有正在运行的进程的数组。然后,我只需检查此进程数组是否包含可用于检测到的OS的终端程序。这不会很聪明,我只需要对Windows,Linux,FreeBSD,Solaris,HP-UX,OS X,AIX的每个可用终端进行硬编码,但仍然可行。它是一个有限的列表。如果某人的终端无法定义,那就无所谓了。它会引发错误,清楚地解释问题以及指向gem的github项目目录的链接,在该目录中,他们可以将其进程名称添加到项目中。无论如何,我的想法看起来像这样(伪代码):
RbConfig::CONFIG['host_os']
现在,这应该适用于大多数情况,但有一个边缘情况让我感到烦恼! 如果他们有两个终端程序同时运行怎么办?例如,如果gnome-terminal和ROXTerm都已安装并正在运行,该怎么办?
我们的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
变量如下所示:utilized
。 我们如何选择哪一个?以下是问题...你是否有一种巧妙的方式我们可以某种方式操纵过程以确定哪个过程是终端&#39 ; s目前正在运行脚本?或者其他的东西?如果这个问题什么都没有,我只是告诉用户只是退出他们不使用的终端,但我喜欢这个能够自动工作,我觉得它是如此可能。脚本已经从终端A执行,终端A和终端B都在运行...所以选择终端A!似乎并不疯狂。
有什么想法吗?请记住,我们正在识别操作系统,因此操作系统特定的黑客行为是可以接受的。
答案 0 :(得分: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: vb@pts/0", "sshd: vb [priv]", "/usr/sbin/sshd -D", "/sbin/init"]