今天下午我先按照昨天的思路写了程序。写函数根据进程号来获取磁盘信息,但是需要安装软件。原打算在运行获取磁盘信息的函数中在catch中增加installTool(String tool)函数,如果系统没有安装iotop软件,则安装然后获取磁盘信息。但是今天我发现没法用程序来调用安装的命令,来安装软件。
这样《迅管家》无法在运行时安装软件,只能在安装《迅管家》时就下载安装相应的软件。
在函数中执行“sudo iotop -p 进程号”执行命令时发现不能执行,应该是需要管理员权限才能执行。然后找到了教程:https://my.oschina.net/u/2391658/blog/1057740 ,然后根据教程想用第一种办法:用密码,不用修改/etc/sudoers文件。
package wl; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; public class process2 { public static void run(String[] cmds) throws IOException, InterruptedException { // /* __debug_code__ for(String cmd : cmds) { System.out.print(cmd); System.out.print(' '); } System.out.println(); // */ Process process = Runtime.getRuntime().exec(cmds); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while((line = input.readLine()) != null) { System.out.println(line); } } public static String[] buildCommands(String cmd, String sudoPasswd) { String[] cmds = {shellName, shellParam, "echo \"" + sudoPasswd + "\" | " + sudoCmd + " -S " + cmd}; return cmds; } protected static String sudoCmd = "sudo"; protected static String shellName = "/bin/bash"; protected static String shellParam = "-c"; public static void main(String[] args) throws IOException, InterruptedException { process2 se = new process2(); String cmd = "cat /etc/sudoers"; process2.run(buildCommands(cmd, "wangli")); } }
但是后来发现,这样需要用户正在登录账号的密码,这样没法得到用户的登录密码。只好用第二种办法,但是发现这种方法需要用到登录的用户名。
whoami命令可以得到用户名,并且不需要管理员权限。但是修改/etc/sudoers文件需要管理员权限。事已至此,感觉在linux系统中用户权限很麻烦。
然后我打算先自己在命令行中修改/etc/sudoers文件,然后接着读取进程的利用率往下做。《迅管家》怎么修改/etc/sudoers文件在项目开发结尾再完成。
但是试了试,没用,这种方法没用,java并不能运行带sudo的linux命令。只能用第一种方法。在《迅管家》安装时让用户输入密码,然后加密保存到文件中,再执行sudo命令时,拿出来用。下面时第二种方法的代码。
package wl; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; public class process2 { public static Object exec(String cmd) { try { String[] cmdA = { "/bin/sh", "-c", cmd }; Process process = Runtime.getRuntime().exec(cmdA); LineNumberReader br = new LineNumberReader(new InputStreamReader( process.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = br.readLine()) != null) { System.out.println(line); sb.append(line).append("\n"); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } public static void run(String[] cmds) throws IOException, InterruptedException { // /* __debug_code__ for(String cmd : cmds) { System.out.print(cmd); System.out.print(' '); } System.out.println(); // */ Process process = Runtime.getRuntime().exec(cmds); InputStreamReader ir = new InputStreamReader(process.getInputStream()); LineNumberReader input = new LineNumberReader(ir); String line; while((line = input.readLine()) != null) { System.out.println(line); } } public static String[] buildCommands(String cmd) // to use this method, you should modify /etc/sudoers { String[] cmds = {shellName, shellParam, sudoCmd + " " + cmd}; return cmds; } protected static String sudoCmd = "sudo"; protected static String shellName = "/bin/bash"; protected static String shellParam = "-c"; public static void main(String[] args) throws IOException, InterruptedException { process2 se = new process2(); String cmd = "cat /etc/sudoers"; process2.run(buildCommands(cmd)); //exec("whoami"); } }
但是这样发现还是不能查询的进程的磁盘利用率。然后百度到:
翻译:如果您希望能够以非根用户的身份运行iotop,我建议您这样做
为Linux编写一个补丁,并将其包含在上游。
我感觉无能为力。