Java - Get pid of process and kill it

這邊主要探討的是,如何用Java去查詢OS內正在運行的process pid,利用所執行的command進行篩選,之後再將其kill掉,主要會分成Windows and Linux進行示範!
流程如下:
1. 撰寫一支程式(BackgroundProgram.java),執行後進行等待直到強制kill掉它為止
2. Export it to Runnable JAR file (命名為reader.jar)
3. 撰寫另一支程式(ProcessManager.java)來進行查詢、刪除的操作

#BackgroundProgram.java
  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileReader;
  5. import java.io.IOException;
  6. public class BackgroundProgram {
  7. public static void main(String args[]){
  8. // TODO Auto-generated method stub
  9. if(args.length != 1) {
  10. System.out.println("Please assign a txt file!!");
  11. System.exit(-1);
  12. }
  13. File file = null;
  14. if(args.length == 1) {
  15. file = new File(args[0]);
  16. if(!file.exists()) {
  17. System.out.println("File non-exist!!");
  18. System.exit(-1);
  19. }
  20. }
  21. try(BufferedReader br = new BufferedReader(new FileReader(file))){
  22. String line = null;
  23. while((line = br.readLine()) != null) {
  24. System.out.println(line);
  25. }
  26. while(true) {
  27. try {
  28. Thread.sleep(5000);
  29. System.out.println("...");
  30. } catch (InterruptedException e) {
  31. // TODO Auto-generated catch block
  32. e.printStackTrace();
  33. }
  34. }
  35. } catch (FileNotFoundException e) {
  36. // TODO Auto-generated catch block
  37. e.printStackTrace();
  38. } catch (IOException e) {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. }
  42. }
  43. }

程式執行時assign一檔案進行讀取與顯示,之後進行等待~
將該程式打包成reader.jar(透過eclipse輸出在此略過),等等執行語法如下:
$ java -jar reader.jar [file path]

#ProcessManager.java
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import java.util.Scanner;
  7. import org.apache.commons.lang3.SystemUtils;
  8. public class ProcessManager {
  9. public static void main(String args[]){
  10. // TODO Auto-generated method stub
  11. Scanner input = new Scanner(System.in);
  12. boolean flag = true;
  13. while(flag) {
  14. System.out.println("(1)List executed 'reader.jar' process (2)Clear executed 'reader.jar' process (3)exit");
  15. int option = input.nextInt();
  16. switch(option) {
  17. case 1:{
  18. getProcessInfo();
  19. break;
  20. }
  21. case 2:{
  22. String killCmd = "";
  23. List<ProcInfo> procLists = getProcessInfo();
  24. for(int i = 0 ; i < procLists.size() ; i++) {
  25. ProcInfo info = procLists.get(i);
  26. String pid = info.getPid();
  27. if(SystemUtils.IS_OS_WINDOWS) {
  28. String windir = System.getenv("windir");
  29. killCmd = windir + "\\System32\\taskkill.exe /F /PID "+pid;
  30. }else
  31. killCmd = "kill -9 "+pid;
  32. Process pp;
  33. try {
  34. pp = Runtime.getRuntime().exec(killCmd);
  35. int exitValue = pp.waitFor();
  36. System.out.println("Exec cmd: "+killCmd+", Status: "+exitValue);
  37. } catch (IOException | InterruptedException e1) {
  38. // TODO Auto-generated catch block
  39. e1.printStackTrace();
  40. }
  41. }
  42. break;
  43. }
  44. case 3:{
  45. flag = false;
  46. input.close();
  47. break;
  48. }
  49. default:{
  50. System.out.println("Option non-exist!!");
  51. }
  52. }
  53. }
  54. }
  55. private static List<ProcInfo> getProcessInfo(){
  56. List<ProcInfo> procLists = new ArrayList<>();
  57. try {
  58. List<String> cmds = new ArrayList<>();
  59. if(SystemUtils.IS_OS_WINDOWS) {
  60. String windir = System.getenv("windir");
  61. cmds.add(windir + "\\System32\\wbem\\WMIC.exe");
  62. cmds.add("process");
  63. cmds.add("where");
  64. cmds.add("caption='java.exe'");
  65. cmds.add("get");
  66. cmds.add("processid,commandline");
  67. }else if(SystemUtils.IS_OS_LINUX) {
  68. cmds.add("/bin/sh");
  69. cmds.add("-c");
  70. cmds.add("ps -eo pid,args | grep java");
  71. }
  72. Process p = Runtime.getRuntime().exec(cmds.toArray(new String[0]));
  73. BufferedReader input2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
  74. String sp = SystemUtils.IS_OS_WINDOWS ? " " : " ";
  75. String line;
  76. while ((line = input2.readLine()) != null) {
  77. line = line.trim();
  78. String spLine[] = line.trim().split(sp);
  79. for(int i = 0 ; i < spLine.length ; i++) {
  80. if(spLine[i].indexOf("reader.jar") > -1) {
  81. String pid = SystemUtils.IS_OS_WINDOWS ? spLine[spLine.length - 1] : spLine[0];
  82. int index = line.indexOf(pid);
  83. String cmd = SystemUtils.IS_OS_WINDOWS ? line.substring(0, index) : line.substring(index + 1);
  84. procLists.add(new ProcInfo(pid, cmd.trim()));
  85. }
  86. }
  87. }
  88. input2.close();
  89. } catch (IOException e) {
  90. // TODO Auto-generated catch block
  91. e.printStackTrace();
  92. }
  93. if(procLists.size() > 0) {
  94. System.out.println("=============Process Lists=============");
  95. System.out.println(procLists);
  96. }else {
  97. System.out.println("None");
  98. }
  99. return procLists;
  100. }
  101. }
  102. class ProcInfo{
  103. private String pid;
  104. private String cmd;
  105. public ProcInfo(String pid, String cmd) {
  106. this.pid = pid;
  107. this.cmd = cmd;
  108. }
  109. public String getPid() {
  110. return pid;
  111. }
  112. public String getCmd() {
  113. return cmd;
  114. }
  115. @Override
  116. public String toString() {
  117. return "Process Info [pid = " + pid + ", executed cmd => " + cmd + "]";
  118. }
  119. }

這支程式重點在getProcessInfo function,區分成Windows and Linux兩種查詢語法
針對主程序為java進行過濾
#Windwos → WMIC.exe process where caption='java.exe' get processid,commandline
回覆結果如下:
CommandLine                     ProcessId
java  -jar reader.jar word.txt  12976
Note: 即使先針對processid但結果還是先印command line

#Linux → /bin/sh -c ps -eo pid,args | grep java
回覆結果如下:
   2190 java -jar reader.jar word.txt
   2282 grep --color=auto java

過濾後會得到pid and commands,再去過濾commands是否有相關keyword,如reader.jar
最後再進行kill
#Windwos → taskkill.exe /F /PID [pid]
#Linux → kill -9 [pid]

DEMO如下:
#Windows - 上: command line執行;中: 查看工作管理員;下: Eclipse執行ProcessManager操作

#Linux - 上: command line執行;中: top;下: command line執行

留言