這邊主要探討的是,如何用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
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BackgroundProgram {
public static void main(String args[]){
// TODO Auto-generated method stub
if(args.length != 1) {
System.out.println("Please assign a txt file!!");
System.exit(-1);
}
File file = null;
if(args.length == 1) {
file = new File(args[0]);
if(!file.exists()) {
System.out.println("File non-exist!!");
System.exit(-1);
}
}
try(BufferedReader br = new BufferedReader(new FileReader(file))){
String line = null;
while((line = br.readLine()) != null) {
System.out.println(line);
}
while(true) {
try {
Thread.sleep(5000);
System.out.println("...");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
程式執行時assign一檔案進行讀取與顯示,之後進行等待~
將該程式打包成reader.jar(透過eclipse輸出在此略過),等等執行語法如下:
$ java -jar reader.jar [file path]
#ProcessManager.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.apache.commons.lang3.SystemUtils;
public class ProcessManager {
public static void main(String args[]){
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
boolean flag = true;
while(flag) {
System.out.println("(1)List executed 'reader.jar' process (2)Clear executed 'reader.jar' process (3)exit");
int option = input.nextInt();
switch(option) {
case 1:{
getProcessInfo();
break;
}
case 2:{
String killCmd = "";
List<ProcInfo> procLists = getProcessInfo();
for(int i = 0 ; i < procLists.size() ; i++) {
ProcInfo info = procLists.get(i);
String pid = info.getPid();
if(SystemUtils.IS_OS_WINDOWS) {
String windir = System.getenv("windir");
killCmd = windir + "\\System32\\taskkill.exe /F /PID "+pid;
}else
killCmd = "kill -9 "+pid;
Process pp;
try {
pp = Runtime.getRuntime().exec(killCmd);
int exitValue = pp.waitFor();
System.out.println("Exec cmd: "+killCmd+", Status: "+exitValue);
} catch (IOException | InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
break;
}
case 3:{
flag = false;
input.close();
break;
}
default:{
System.out.println("Option non-exist!!");
}
}
}
}
private static List<ProcInfo> getProcessInfo(){
List<ProcInfo> procLists = new ArrayList<>();
try {
List<String> cmds = new ArrayList<>();
if(SystemUtils.IS_OS_WINDOWS) {
String windir = System.getenv("windir");
cmds.add(windir + "\\System32\\wbem\\WMIC.exe");
cmds.add("process");
cmds.add("where");
cmds.add("caption='java.exe'");
cmds.add("get");
cmds.add("processid,commandline");
}else if(SystemUtils.IS_OS_LINUX) {
cmds.add("/bin/sh");
cmds.add("-c");
cmds.add("ps -eo pid,args | grep java");
}
Process p = Runtime.getRuntime().exec(cmds.toArray(new String[0]));
BufferedReader input2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
String sp = SystemUtils.IS_OS_WINDOWS ? " " : " ";
String line;
while ((line = input2.readLine()) != null) {
line = line.trim();
String spLine[] = line.trim().split(sp);
for(int i = 0 ; i < spLine.length ; i++) {
if(spLine[i].indexOf("reader.jar") > -1) {
String pid = SystemUtils.IS_OS_WINDOWS ? spLine[spLine.length - 1] : spLine[0];
int index = line.indexOf(pid);
String cmd = SystemUtils.IS_OS_WINDOWS ? line.substring(0, index) : line.substring(index + 1);
procLists.add(new ProcInfo(pid, cmd.trim()));
}
}
}
input2.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(procLists.size() > 0) {
System.out.println("=============Process Lists=============");
System.out.println(procLists);
}else {
System.out.println("None");
}
return procLists;
}
}
class ProcInfo{
private String pid;
private String cmd;
public ProcInfo(String pid, String cmd) {
this.pid = pid;
this.cmd = cmd;
}
public String getPid() {
return pid;
}
public String getCmd() {
return cmd;
}
@Override
public String toString() {
return "Process Info [pid = " + pid + ", executed cmd => " + cmd + "]";
}
}
這支程式重點在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執行
留言
張貼留言