java执行linux命令查询信息

java执行linux命令查询信息_第1张图片

一、使用方式

方式1:只创建“读取标准输出流”

public Map<String, String> getHostnameAndSystem() {
	Map<String, String> map = new HashMap<>();
	InputStream in = null;
	BufferedReader read = null;
	Process pro = null;
	String cmd = "hostnamectl | awk -F': +' '/Static hostname|Operating System/ {printf \"%s,\", $2}' | sed 's/,$//'";
	String[] cmds = null;
	try {
		String result = getSingleResult(cmd, cmds, pro, in, read);
		logger.info("result:{}", result);
		String[] split = result.split(",");
		map.put("hostname", split[0]);
		map.put("os", split[1]);
	} catch (IOException | InterruptedException e) {
		logger.error("-getHostnameAndSystem-Exception:{}", e);
		return null;
	} finally {
		try {
			if (pro != null) {
				pro.destroy();
			}
			if (read != null) {
				read.close();
			}
			if (in != null) {
				in.close();
			}
		} catch (IOException e) {
			logger.error("-getHostnameAndSystem-finally-IOException:{}", e);
		}
	}
	return map;
}


public static String getSingleResult(String cmd, String[] cmds, Process pro, InputStream in, BufferedReader read) throws IOException, InterruptedException {
	cmds = new String[]{"/bin/sh", "-c", cmd};
	logger.info("-cmd:{}", cmd);
	pro = Runtime.getRuntime().exec(cmds);
	if (pro.waitFor() == 0) {
		String line = "";
		in = pro.getInputStream();
		read = new BufferedReader(new InputStreamReader(in));
		while ((line = read.readLine()) != null) {
			logger.info("-line:{}", line);
			return line;
		}
	}
	return null;
}

方式2:创建“读取标准输出流”+“读取标准错误流”

public Map<String, String> getHostnameAndSystem() {
	String[] cmds = null;
	Process pro = null;
	InputStream in = null;
	BufferedReader read = null;
	String errorMessage = "";
	
	try {
		String cmd = "hostnamectl | awk -F': +' '/Static hostname|Operating System/ {printf \"%s,\", $2}' | sed 's/,$//'";
        getSingleResult(cmd, cmds, pro, in, read);
	} catch (Exception e) {
		e.printStackTrace();
		logger.error("-kerberosKeytabUpload-e:{}", e.getMessage());
		List<String> fileContent = null;
		try {
			fileContent = FileUtil.getFileContent(FILE_STORE_PATH + "verifyError.txt");
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
		for (String line : fileContent) {
			errorMessage += line + " ";
		}
	}	
}

public static String getSingleResult(String cmd, String[] cmds, Process pro, InputStream in, BufferedReader read) throws IOException, InterruptedException {
	cmds = new String[]{"/bin/sh", "-c", cmd};
	logger.info("ldapPublicKeyUpload-cmd:{}", cmd);
	pro = Runtime.getRuntime().exec(cmds);

	int exitCode = pro.waitFor();

	try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(pro.getInputStream()));
		 BufferedReader stdError = new BufferedReader(new InputStreamReader(pro.getErrorStream()))) {

		StringBuilder output = new StringBuilder();
		String line;

		// 读取标准输出
		while ((line = stdInput.readLine()) != null) {
			logger.info("stdInput-line:{}", line);
			output.append(line).append("\n");
		}

		// 读取标准错误
		StringBuilder errorOutput = new StringBuilder();
		while ((line = stdError.readLine()) != null) {
			logger.info("stdError-line:{}", line);
			errorOutput.append(line).append("\n");
		}

		// 检查退出码
		if (exitCode == 0) {
			logger.info("Command success with exit exitCode :{}, output: {}", exitCode, output.toString());
			return output.toString();
		} else {
			logger.error("Command failed with exit exitCode :{}, errorOutput: {}", exitCode, errorOutput.toString());
			throw new IOException(errorOutput.toString());
		}
	}
}

二、注意点说明

注意点1:这两种方式使用场景不一样

  • 方式1,适用于查询CPU之类的直接返回结果。
  • 方式2,适用于第三方下发命令,比如上传证书之类的,可能成功也可能失败,如果失败想捕获错误信息当接口返回值直接返回。

注意点2:两种方式实现逻辑不一样,方式1 只是捕获line读取结果直接返回,这种方式可以正确获取想要的结果;但是方式2中line是可以打印到结果的,但是最终拼接output和errorOutput最后值都是空,发现无法拼接进去值,比如如图line打印出来值了,但是最后打印的output和errorOutput都是空白。

问题:如果碰到这样该怎么办呢?

答案:把错误信息写入到文件中,然后在读取出来,封装返回对象中接口返回。

举例

/**
* Upload ldap public Key
 * @param multipartFile multipartFile
 * @param request request
 * @param id id
 * @return 结果
 */
@ResponseBody
@SuppressWarnings("deprecation")
@RequestMapping("ldapPublicKeyUpload")
public ResultSet ldapPublicKeyUpload(@RequestParam("ldapPublicKeyFile") MultipartFile multipartFile, HttpServletRequest request, @RequestParam("id") Integer id) {
    logger.info("-ldapPublicKeyUpload-id:{}", id);
    ResultSet resultSet =  new ResultSet();
    String[] cmds = null;
    Process pro = null;
    InputStream in = null;
    BufferedReader read = null;
    String errorMessage = "";
    String FILE_STORE_PATH = "/home/ems/ems_file/ldap/ldapServerConfig/";
    String imgName = "ldap_keystore.cer";
    try {
        if (multipartFile.isEmpty() || multipartFile.getSize() == 0L) {
            resultSet.setErrorCode(LteResultCodeEnum.FILE_CONTENT_EMPTY.getErrorCode());
            resultSet.setErrorString(MessageAccessor.getMessage(LteResultCodeEnum.FILE_CONTENT_EMPTY.getErrorCode()));
            return resultSet;
        }
        String originalFilename = multipartFile.getOriginalFilename();
        File file = new File(FILE_STORE_PATH + "ldap_keystore.jks");
        String password = new String(Base64.getDecoder().decode(LdapConstants.KEYSTORE_PASSWORD));
        if (file.exists()) {
            String cmd = "/home/ems/3rdparty/java/bin/keytool -delete -alias ad-server-cert " + " -keystore " + FILE_STORE_PATH + imgName.split("\\.")[0] + ".jks -storepass " + password;
            getSingleResult(cmd, cmds, pro, in, read);
            boolean delete = file.delete();
            logger.info("execute delete jks file result:{}", delete);
        }
        file = new File(FILE_STORE_PATH + originalFilename);
        if (!file.getParentFile().exists()) {
            logger.info("Creating directory: " + file.getParentFile());
            file.getParentFile().mkdirs(); // 递归创建父目录
        }

        multipartFile.transferTo(file);
        if (!originalFilename.toLowerCase().endsWith(".jks")) {
            String cmd = "/home/ems/3rdparty/java/bin/keytool -import -noprompt -alias ad-server-cert -file " + FILE_STORE_PATH + originalFilename + " -keystore " + FILE_STORE_PATH + imgName.split("\\.")[0] + ".jks -storepass " + password + " > " + FILE_STORE_PATH + "verifyError.txt";
            String result = getSingleResult(cmd, cmds, pro, in, read);
            logger.info("-ldapPublicKeyUpload-result:{}", result);
            if (result != null) {
                return new ResultSet(originalFilename);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        logger.error("-kerberosKeytabUpload-e:{}", e.getMessage());
        List<String> fileContent = null;
        try {
            fileContent = FileUtil.getFileContent(FILE_STORE_PATH + "verifyError.txt");
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        for (String line : fileContent) {
            errorMessage += line + " ";
        }
    }
    if (errorMessage.contains("Input not an X.509 certificate")) {
        return new ResultSet(new LteException(LteResultCodeEnum.INPUT_NOT_AN_X509_CERTIFICATE.getErrorCode()));
    } else {
        return new ResultSet(new LteException(LteResultCodeEnum.UPLOAD_FILE_FAILED.getErrorCode()));
    }
}

public static String getSingleResult(String cmd, String[] cmds, Process pro, InputStream in, BufferedReader read) throws IOException, InterruptedException {
  cmds = new String[]{"/bin/sh", "-c", cmd};
    logger.info("ldapPublicKeyUpload-cmd:{}", cmd);
    pro = Runtime.getRuntime().exec(cmds);

    int exitCode = pro.waitFor();

    try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(pro.getInputStream()));
         BufferedReader stdError = new BufferedReader(new InputStreamReader(pro.getErrorStream()))) {

        StringBuilder output = new StringBuilder();
        String line;

        // 读取标准输出
        while ((line = stdInput.readLine()) != null) {
            logger.info("stdInput-line:{}", line);
            output.append(line).append("\n");
        }

        // 读取标准错误
        StringBuilder errorOutput = new StringBuilder();
        while ((line = stdError.readLine()) != null) {
            logger.info("stdError-line:{}", line);
            errorOutput.append(line).append("\n");
        }

        // 检查退出码
        if (exitCode == 0) {
            logger.info("Command success with exit exitCode :{}, output: {}", exitCode, output.toString());
            return output.toString();
        } else {
            logger.error("Command failed with exit exitCode :{}, errorOutput: {}", exitCode, errorOutput.toString());
            throw new IOException(errorOutput.toString());
        }
    }
}

你可能感兴趣的:(JAVA相关,java,linux,执行linux命令,java执行linux命令,执行命令,linux命令)