您的位置:首页 > 运维架构 > Shell

runtime.exec()方法执行shell脚本中有管道符的问题解决

2018-01-24 09:56 627 查看
今天在修改项目公共模块代码的时候遇到一个问题,通过RunTime方法执行shell方法时遇到脚本中存在管道符时报错问题。解决方法如下

  


以下附上公共类代码:

package com.centerm.ivycloud.vcenter.share.commontools.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.centerm.ivycloud.vcenter.share.commontools.bean.ExecResult;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

public class ShellUtil {
private static Logger log = Logger.getLogger(ShellUtil.class);

private static String HOSTIP = "127.0.0.1";
private static String USER = "root";
private static String PASS = "centerm";
private String LOCAL = "1";//local 1为本地执行,其他为远程执行
private File FILE = null;
public ShellUtil(String hOSTIP, String uSER, String pASS, String lOCAL) {
super();
HOSTIP = hOSTIP;
USER = uSER;
PASS = pASS;
LOCAL = lOCAL;
}

public ShellUtil(String hOSTIP, String uSER, String pASS) {
super();
HOSTIP = hOSTIP;
USER = uSER;
PASS = pASS;
LOCAL = "1";
}

public ShellUtil(String hOSTIP, String uSER, File file,String local) {
super();
HOSTIP = hOSTIP;
USER = uSER;
FILE = file;
LOCAL = local;
}

public ShellUtil(String hOSTIP, String uSER, File file) {
super();
HOSTIP = hOSTIP;
USER = uSER;
FILE = file;
LOCAL = "1";
}

public static void main(String[] args){
ShellUtil shellUtil = new ShellUtil("192.168.127.163","root","centerm");
ExecResult r = shellUtil.execGetResult("qemu-img check /IvyCloud/cv-data/image-repo/win73D1227-2.img --output json 2>/dev/null", 1);
System.out.println(r.getCode());
System.out.println(r.getResult());
}
/**
*
* @param cmd 命令
* @param flag flag为1是远程执行, 不传就判断LOCAL是否为1,如果为1为本地执行,
* @return
*/
public String exec(String cmd, int ...flag) {
int retryTime = 0;
String result = "";

if(flag.length != 0 && flag[0] == 1){
log.debug("exec flag == 1");
return exeRemoteCommandGetOutput(cmd, 1);
}

try {
if(LOCAL.equals("1")){
result = exeLocalCommandGetOutput(cmd);
}else{
result = exeRemoteCommandGetOutput(cmd);
}
} catch (Exception e) {
log.error("exec cmd exception:"+cmd,e);
}

return result;
}

public ExecResult execLocalGetResult(String cmd){
// 得到Java进程的相关Runtime运行对象
Runtime runtime = Runtime.getRuntime();
ExecResult re = new ExecResult();

try {
// 利用exec()方法执行shell 命令 ls -al /root ,并且返回一个Process对象 也就是子进程
// ps:这里都以最简单的shell命令举例。
Process process = runtime.exec(cmd);
log.debug("exe cmd: " + cmd);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader bufferStdErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));

StringBuffer stringBuffer = new StringBuffer();
StringBuffer stringErrBuffer = new StringBuffer();
String temp = null;
String temp2 = n
4000
ull;

while ((temp = bufferReader.readLine()) != null ||
(temp2 = bufferStdErr.readLine())!= null) {
if(temp != null){
stringBuffer.append(temp);
}

if(temp2 != null){
stringErrBuffer.append(temp2);
}
}

int code = process.waitFor();
log.debug("execLocalGetResult Exit code "+code+":"+stringBuffer+", errMsg:"+stringErrBuffer);
re.setCode(code);
re.setResult(stringBuffer.toString());
} catch (Exception e) {
re.setCode(-101);
re.setResult("");
log.error("execLocalGetResult error :" +cmd, e);
}

return re;
}

public String exeLocalCommandGetOutput(String cmd) {
// 得到Java进程的相关Runtime运行对象
Runtime runtime = Runtime.getRuntime();

try {
// 利用exec()方法执行shell 命令 ls -al /root ,并且返回一个Process对象 也就是子进程
// ps:这里都以最简单的shell命令举例。
Process process = null;
if(cmd.indexOf("|")>0){
String[] cmdArr = {"sh","-c",cmd};
process = runtime.exec(cmdArr);
}else{
process = runtime.exec(cmd);
}

log.debug("exe cmd: " + cmd);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader bufferStdErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));

StringBuffer stringBuffer = new StringBuffer();
StringBuffer stringErrBuffer = new StringBuffer();
String temp = null;
String temp2 = null;

while ((temp = bufferReader.readLine()) != null) {
if(temp.equals("")){
stringBuffer.append(temp);
}else{
stringBuffer.append(temp+'\n');
}
}

while((temp2 = bufferStdErr.readLine())!= null){
stringErrBuffer.append(temp2);
}

int code = process.waitFor();
log.debug("exeLocalCommandGetOutput Exit code "+code+":"+stringBuffer+", errMsg:"+stringErrBuffer);
return stringBuffer.toString();
} catch (Exception e) {
log.error("exeLocalCommandGetOutput error :"+cmd, e);
return null;
}
}

public List<String> getExecLocalResult(String cmd){
List<String> result = new ArrayList<String>();

Runtime runtime = Runtime.getRuntime();

try {
// 利用exec()方法执行shell 命令 ls -al /root ,并且返回一个Process对象 也就是子进程
// ps:这里都以最简单的shell命令举例。
Process process = runtime.exec(cmd);
log.debug("exe cmd: " + cmd);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

StringBuffer stringBuffer = new StringBuffer();
String temp = null;

while ((temp = bufferReader.readLine()) != null) {
result.add(temp);
stringBuffer.append(temp);
// 磁盘挂载或卸载失败,目前先这样临时处理。后续再统一对错误码进行处理
if (temp.contains("exception ubd disk")) {
break;
}
}

int code = process.waitFor();
log.debug("getExecLocalResult Exit code "+code+":"+stringBuffer);
} catch (Exception e) {
log.error("getExecLocalResult error :"+cmd, e);
}

return result;
}

public ExecResult execGetResult(String cmd, int ...flag){
if(flag.length == 0 || flag[0]!=1){
if(LOCAL.equals("1")){
log.debug("exeRemoteCommandGetOutput LOCAL = 1");
return execLocalGetResult(cmd);
}
}

int ret = 0;
String result = "";
ExecResult re = new ExecResult();

try {
// 建立连接
Connection conn = new Connection(HOSTIP);
log.debug("set up connections");
conn.connect();
// 利用用户名和密码进行授权
/*boolean isAuthenticated = conn.authenticateWithPassword(USER,
PASS);*/
boolean isAuthenticated = conn.authenticateWithPublicKey(USER, FILE, null);
if (!isAuthenticated) {
throw new Exception("Authorication failed");
}

// 打开会话
Session sess = conn.openSession();
sess.execCommand(cmd);

log.debug("exe cmd: " + cmd);

// 执行命令
log.debug("The execute command output is:");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true) {
String line = br.readLine();
if (line == null) {
break;
}

log.debug(line);
result += line;
}

log.debug("execGetResult Exit code " + ret+":"+result);

re.setCode(ret);
re.setResult(result);

if(sess != null){
sess.close();
}

if(conn != null){
conn.close();
}

if(br != null){
br.close();
}
log.debug("Connection closed");
} catch (Exception e) {
log.error("can not access the remote machine :" +cmd,e);
// 特殊标志
re.setCode(-101);
re.setResult("");
}

return re;
}

public String exeRemoteCommandGetOutput(String cmd, int ...flag) {
if(flag.length == 0 || flag[0]!=1){
if(LOCAL.equals("1")){
log.debug("exeRemoteCommandGetOutput LOCAL = 1");
return exeLocalCommandGetOutput(cmd);
}
}

log.debug("exeRemoteCommandGetOutput flag = 1");

int ret = 0;
String result = "";

try {
// 建立连接
Connection conn = new Connection(HOSTIP);
log.debug("set up connections");
conn.connect();
// 利用用户名和密码进行授权
boolean isAuthenticated = conn.authenticateWithPublicKey(USER, FILE, null);
if (!isAuthenticated) {
throw new Exception("Authorication failed");
}

// 打开会话
Session sess = conn.openSession();
sess.execCommand(cmd);

log.debug("exe cmd: " + cmd);

// 执行命令
log.debug("The execute command output is:");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true) {
String line = br.readLine();
if (line == null) {
break;
}

log.debug(line);
if(line.equals("")){
result += line;
}else{
result = result+line+'\n';
}
}

// 脚本执行的内部返回值
if (ret == 0) {
ret = sess.getExitStatus();
} else {
// 已经是失败了
sess.getExitStatus();
}
log.debug("exeRemoteCommandGetOutput Exit code " + ret+":"+result);

if(sess != null){
sess.close();
}

if(conn != null){
conn.close();
}

if(br != null){
br.close();
}

log.debug("Connection closed");
} catch (Exception e) {
log.error("can not access the remote machine :" +cmd,e);
result = null;
}

return result;
}

public List<String> getExecResult(String cmd) {
List<String> result = new ArrayList<String>();

try {
// 建立连接
Connection conn = new Connection(HOSTIP);
log.debug("set up connections");
conn.connect();
// 利用用户名和密码进行授权
/*boolean isAuthenticated = conn.authenticateWithPassword(USER,
PASS);*/
boolean isAuthenticated = conn.authenticateWithPublicKey(USER, FILE, null);
if (!isAuthenticated) {
throw new Exception("Authorication failed");
}

// 打开会话
Session sess = conn.openSession();

log.debug("exe cmd: " + cmd);

sess.execCommand(cmd);

// 执行命令
log.debug("The execute command output is:");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true) {
String line = br.readLine();
if (line == null) {
break;
}

result.add(line);
// 磁盘挂载或卸载失败,目前先这样临时处理。后续再统一对错误码进行处理
if (line.contains("exception ubd disk")) {
break;
}
}

sess.close();
conn.close();
log.debug("Connection closed");
} catch (Exception e) {
log.error("can not access the remote machine :"+cmd, e);
// 特殊标志
}

return result;
}

public long getImageSize(String sourceImagePath) {
String cmd = "du " + sourceImagePath + " -b";
List<String> result = null;
if(LOCAL.equals("1")){
result = getExecLocalResult(cmd);
}else{
result = getExecResult(cmd);
}

if (result == null || result.size() <= 0) {
return 0;
}
String resultStr = result.get(0);
String[] resultParam = resultStr.split("\t");
if (resultParam == null || resultParam.length == 0) {
return 0;
}
String sizeStr = resultParam[0];
long size = Long.parseLong(sizeStr.trim());

return size;
}

public void deleteFile(String filePath){
exec("rm -f "+filePath);
}

public void copyFile(String sourceFilePath, String targetFilePath){
exec("cp -f "+sourceFilePath+" "+ targetFilePath);
}

public ExecResult copyFileGetResult(String sourceFilePath, String targetFilePath){
ExecResult result = execGetResult("cp -f "+sourceFilePath+" "+ targetFilePath);
return result;
}

public void moveFile(String sourceFilePath, String targetFilePath){
exec("mv -f "+sourceFilePath+" "+ targetFilePath);
}

public String[] getSubFiles(String path){
String str = exec("ls "+path);
if(str == null){
return null;
}
String[] strt = str.split("\n");
return strt;
}

public long getImageRepoSurplus(){
String str = exec("df -P -B 1 /IvyCloud/cv-data/image-repo/ | grep \'^/\' | awk \'{ print $4 }\'");
str = str.trim();
try{
long size = Long.parseLong(str);
return size;
}catch(Exception e){
return 0;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: