方式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
:这两种方式使用场景不一样
注意点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());
}
}
}