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

本文介绍了在使用Java的Runtime.exec()方法执行含有管道符的shell脚本时遇到的问题及解决方法,提供了相关的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在修改项目公共模块代码的时候遇到一个问题,通过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 = null;

			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;
		}
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值