我在 OSX 上有一个应用程序反复进入无响应状态,必须强制终止。我本来希望可以自动完成此操作,但在使用以下程序检查进程时附言我没有看到任何与“无响应”状态相对应的内容。我查看了状态指示器,但应用程序显示为年代无论它是否响应。
state 状态由一串字符给出,例如“RWNA”。第一个字符表示进程的运行状态:
- I 标记处于空闲状态(休眠时间超过 20 秒)的进程。
- R 标记可运行的进程。
- S 标记休眠时间少于 20 秒的进程。
- T 标记已停止的进程。
- U 标记进程处于不可中断等待状态。
- Z 标记一个死亡进程(“僵尸”)。
我如何确定进程是否未响应就像活动管理器那样?
我也对 AppleScript 解决方案持开放态度。
答案1
“无响应”状态不是进程状态,而是进程已停止与窗口管理器/图形引擎通信。它可能被绑定在循环中,挂在套接字、远程文件上,或任何使其返回处理事件的主循环的东西上。窗口管理器注意到事件正在排队,因此将其标记为“无响应”
您可能需要编写一个小型的 X11 程序,向该进程发送虚拟事件,然后在该进程没有响应时将其终止。
答案2
这是一个使用 UI 脚本的 AppleScript,它查找没有响应的进程并将其终止。
它将与 Mavericks 的活动监视器配合使用。但由于这是 UI 脚本,并且活动监视器的 UI 已更改,因此如果不进行一些小修改,它很可能无法与旧版 OS X 配合使用。
tell application "Activity Monitor" to run --We need to run Activity Monitor
tell application "System Events" to tell process "Activity Monitor"
tell radio button 1 of radio group 1 of group 1 of toolbar 1 of window 1 to click --Using the CPU View
tell outline 1 of scroll area 1 of window 1 -- working with the list
set notResponding to rows whose value of first static text contains "Not Responding" -- Looking for Not responding process
repeat with aProcess in notResponding
set pid to value of text field 5 of aProcess -- For each non responding process retrieve the PID
if pid is not "" then do shell script ("kill -9 " & pid) -- KILL the PID.
end repeat
end tell
end tell
答案3
(由于太长而无法在评论中容纳,因此将其作为单独的答案发布)
感谢@MatthieuRiegler 提供原始脚本。
这在 10.12.6 上运行良好,并且是对原始脚本的一个小修改(在我进行自己的调查后看到了@CharlieGorichanaz 的评论):
set textToSearchForInProcessName to "Not Responding"
-- Run Activity Monitor
tell application "Activity Monitor" to activate
tell application "System Events" to tell process "Activity Monitor"
-- Wait for the Activity Monitor window to open
repeat until (exists window 1)
delay 1
end repeat
--display notification "Window appeared"
-- Wait for the Menubar to be present
repeat until (exists menu 1 of menu bar item "View" of menu bar 1)
delay 1
end repeat
--display notification "Menubar appeared"
-- Make sure View -> My Processes is selected
click menu item "My Processes" of menu 1 of menu bar item "View" of menu bar 1
-- Click the 'CPU View' button ( **1 )
click radio button 1 of radio group 1 ¬
of group 2 of toolbar 1 ¬
of window 1
-- Working with the list of processes
tell outline 1 of scroll area 1 of window 1
-- Looking for Not responding process
set notResponding to rows whose value of ¬
first static text contains textToSearchForInProcessName
repeat with aProcess in notResponding
-- For each non responding process retrieve the PID
set pid to value of text field 1 of aProcess -- ( **2 )
-- Kill that process using pid
if pid is not "" then do shell script ("kill -9 " & pid)
end repeat
end tell
end tell
**1
在 macOS 10.12.x 中,工具栏包含一个附加图标,因为按钮组(CPU、内存、能量等)位于 group 2 of toolbar 1
而不是group 1 of toolbar 1
。如果没有该图标(我尚未在旧版 macOS 中确认),我相信 CPU 等按钮应该位于group 1 of toolbar 1
**2
如果您曾将“活动”列中的 PID 列拖到其他位置,则适用此情况。我已将 PID 列拖到最左侧的位置,因此在此行上,我必须将索引更改为1
:
set pid to value of text field 1 of aProcess
列从最左边开始编号,从 1 开始。因此,如果需要,请相应地调整上面一行中突出显示的索引。