<转>JSCH 如何实现在远程机器上执行linux命令

6 篇文章 0 订阅
原链:http://blog.csdn.net/hongbinchen/article/details/6567395

jsch 是纯java实现ssh功能,
下面是如何实现在远程机器上执行linux命令
摘自hadoop开源包的源码:



/**

* Licensed to the Apache Software Foundation (ASF) under one

* or more contributor license agreements. See the NOTICE file

* distributed with this work for additional information

* regarding copyright ownership. The ASF licenses this file

* to you under the Apache License, Version 2.0 (the

* "License"); you may not use this file except in compliance

* with the License. You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/



package org.apache.hadoop.util;



import com.jcraft.jsch.*;

import org.apache.commons.logging.LogFactory;

import org.apache.commons.logging.Log;



import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Properties;



/**

* Remote Execution of commands on a remote machine.

*/



public class SSHRemoteExecution implements RemoteExecution {



static final Log LOG = LogFactory.getLog(SSHRemoteExecution.class);

static final int SSH_PORT = 22;

static final String DEFAULT_IDENTITY="id_dsa";

static final String DEFAULT_KNOWNHOSTS="known_hosts";

static final String FS = System.getProperty("file.separator");

static final String LS = System.getProperty("line.separator");

private int exitCode;

private StringBuffer output;

private String commandString;



final StringBuffer errorMessage = new StringBuffer();

public SSHRemoteExecution() throws Exception {

}



protected String getHomeDir() {

String currentUser=System.getProperty("user.name");

String userHome=System.getProperty("user.home");



return userHome.substring(0, userHome.indexOf(currentUser)-1);

}



/**

* Execute command at remote host under given user

* @param remoteHostName remote host name

* @param user is the name of the user to be login under;

* current user will be used if this is set to <code>null</code>

* @param command to be executed remotely

* @param identityFile is the name of alternative identity file; default

* is ~user/.ssh/id_dsa

* @param portNumber remote SSH daemon port number, default is 22

* @throws Exception in case of errors

*/

public void executeCommand (String remoteHostName, String user,

String command, String identityFile, int portNumber) throws Exception {

commandString = command;

String sessionUser = System.getProperty("user.name");

String userHome=System.getProperty("user.home");

if (user != null) {

sessionUser = user;

userHome = getHomeDir() + FS + user;

}

String dotSSHDir = userHome + FS + ".ssh";

String sessionIdentity = dotSSHDir + FS + DEFAULT_IDENTITY;

if (identityFile != null) {

sessionIdentity = identityFile;

}



JSch jsch = new JSch();



Session session = jsch.getSession(sessionUser, remoteHostName, portNumber);

jsch.setKnownHosts(dotSSHDir + FS + DEFAULT_KNOWNHOSTS);

jsch.addIdentity(sessionIdentity);



Properties config = new Properties();

config.put("StrictHostKeyChecking", "no");

session.setConfig(config);



session.connect(30000); // making a connection with timeout.



Channel channel=session.openChannel("exec");

((ChannelExec)channel).setCommand(command);

channel.setInputStream(null);



final BufferedReader errReader =

new BufferedReader(

new InputStreamReader(((ChannelExec)channel).getErrStream()));

BufferedReader inReader =

new BufferedReader(new InputStreamReader(channel.getInputStream()));



channel.connect();

Thread errorThread = new Thread() {

@Override

public void run() {

try {

String line = errReader.readLine();

while((line != null) && !isInterrupted()) {

errorMessage.append(line);

errorMessage.append(LS);

line = errReader.readLine();

}

} catch(IOException ioe) {

LOG.warn("Error reading the error stream", ioe);

}

}

};



try {

errorThread.start();

} catch (IllegalStateException e) {

LOG.debug(e);

}

try {

parseExecResult(inReader);

String line = inReader.readLine();

while (line != null) {

line = inReader.readLine();

}



if(channel.isClosed()) {

exitCode = channel.getExitStatus();

LOG.debug("exit-status: " + exitCode);

}

try {

// make sure that the error thread exits

errorThread.join();

} catch (InterruptedException ie) {

LOG.warn("Interrupted while reading the error stream", ie);

}

} catch (Exception ie) {

throw new IOException(ie.toString());

}

finally {

try {

inReader.close();

} catch (IOException ioe) {

LOG.warn("Error while closing the input stream", ioe);

}

try {

errReader.close();

} catch (IOException ioe) {

LOG.warn("Error while closing the error stream", ioe);

}

channel.disconnect();

session.disconnect();

}

}



/**

* Execute command at remote host under given username

* Default identity is ~/.ssh/id_dsa key will be used

* Default known_hosts file is ~/.ssh/known_hosts will be used

* @param remoteHostName remote host name

* @param user is the name of the user to be login under;

* if equals to <code>null</code> then current user name will be used

* @param command to be executed remotely

*/

@Override

public void executeCommand (String remoteHostName, String user,

String command) throws Exception {

executeCommand(remoteHostName, user, command, null, SSH_PORT);

}



@Override

public int getExitCode() {

return exitCode;

}



protected void parseExecResult(BufferedReader lines) throws IOException {

output = new StringBuffer();

char[] buf = new char[512];

int nRead;

while ( (nRead = lines.read(buf, 0, buf.length)) > 0 ) {

output.append(buf, 0, nRead);

}

}



/** Get the output of the ssh command.*/

@Override

public String getOutput() {

return (output == null) ? "" : output.toString();

}



/** Get the String representation of ssh command */

@Override

public String getCommandString() {

return commandString;

}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值