码迷,mamicode.com
首页 > 编程语言 > 详细

Java调用 shell脚本阻塞

时间:2015-06-11 11:13:55      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:java   shell   阻塞   输出流   

  Java在调用Shell时,要不断读取进程中标准输出和错误输出流的信息,否则缓冲区被写满就会造成子进程阻塞而无法继续运行下去,可起两个线程不断读取标准输出、错误流信息而不被阻塞

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.commons.io.IOUtils;

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


public class RmtShellExecutor {

	
	private Connection conn;
	private String ip;
	private String usr;
	private String psword;
	private String charset = Charset.defaultCharset().toString();

	private static final int TIME_OUT = 1000 * 5 * 60;

	public RmtShellExecutor(String ip, String usr, String ps) {
		this.ip = ip;
		this.usr = usr;
		this.psword = ps;
	}

	private boolean login() throws IOException {
		conn = new Connection(ip);
		conn.connect();
		return conn.authenticateWithPassword(usr, psword);
	}

	//本地执行方法
	public static void execLocal(String cmd) {
	       try {
				Process proc = Runtime.getRuntime().exec(cmd);
				StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
				StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
				errorGobbler.start();
				outputGobbler.start();
				int exitVal = proc.waitFor();
		        System.out.println("ExitValue: " + exitVal);
		     } catch (Exception e) {
				  e.printStackTrace();
		     } 
			
		}
        
    //远程执行方法
	public int execRemote(String cmds){
		InputStream stdOut = null;
		InputStream stdErr = null;
		int ret = -1;
		try {
			if (login()) {
				// Open a new {@link Session} on this connection
				Session session = conn.openSession();
				// Execute a command on the remote machine.
				session.execCommand(cmds);

				GobblerThread gtOut = new GobblerThread(session.getStdout(),"STD_OUT");
				GobblerThread gtErr = new GobblerThread(session.getStderr(),"STD_ERR");
				gtOut.start();
				gtErr.start();

				session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
				ret = session.getExitStatus();
			} else {
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		finally {
			if (conn != null) {
				conn.close();
			}
			IOUtils.closeQuietly(stdOut);
			IOUtils.closeQuietly(stdErr);
		}
		return ret;
	}

	public static void main(String args[]) throws Exception {
		RmtShellExecutor exe = new RmtShellExecutor("192.168.3.5", "test",
				"123456");
		System.out.println(exe.execRemote("sh /home/test/cmd.sh company=32"));
	}
}

class GobblerThread extends Thread
{
    InputStream is;
    String type;
    
    GobblerThread(InputStream is, String type)
    {
        this.is = is;
        this.type = type;
    }
    
    public void run()
    {
        try
        {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
                System.out.println(line);    
            } catch (IOException e)
              {
                e.printStackTrace();  
              }
    }
}

execLocal 为本地调用cmd的方法

exeRemote 可利用ssh登录远程机器调用cmd的方法


参考文章:http://www.linuxidc.com/Linux/2014-04/99557.htm

本文出自 “脚踏实地,仰望星空” 博客,请务必保留此出处http://xubcing.blog.51cto.com/3502962/1660692

Java调用 shell脚本阻塞

标签:java   shell   阻塞   输出流   

原文地址:http://xubcing.blog.51cto.com/3502962/1660692

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!