前面一篇文章写道利用jsch 包远程执行linux 命令,但是该包已经很久没有更新, 后期linux 的open-ssh 升级,可能部分协议不支持,发现mina-sshd 里面有一个还在维护的远程执行 linux shell 命令的包
代码demo 如下
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.future.ConnectFuture;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.util.io.input.NoCloseInputStream;
import org.apache.sshd.common.util.io.output.NoCloseOutputStream;
import util.SshConnection;
public final class SshUtils {
public static SshResponse runCommand(SshConnection conn, String cmd, long timeout)
throws SshTimeoutException, IOException {
SshClient client = SshClient.setUpDefaultClient();
try {
// Open the client
client.start();
// Connect to the server
ConnectFuture cf = client.connect(conn.getUsername(), conn.getHostname(), 22);
ClientSession session = cf.verify().getSession();
session.addPasswordIdentity(conn.getPassword());
session.auth().verify(TimeUnit.SECONDS.toMillis(timeout));
// Create the exec and channel its output/error streams
ChannelExec ce = session.createExecChannel(cmd);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
ce.setOut(out);
ce.setErr(err);
// Execute and wait
ce.open();
Set<ClientChannelEvent> events =
ce.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(timeout));
session.close(false);
// Check if timed out
if (events.contains(ClientChannelEvent.TIMEOUT)) {
throw new SshTimeoutException(cmd, conn.getHostname(), timeout);
}
return new SshResponse(out.toString(), err.toString(), ce.getExitStatus());
} finally {
client.stop();
}
}
/**
* 交互式命令发送
* @param conn
* @param timeout
* @throws SshTimeoutException
* @throws IOException
*/
public static void runCommandForInteractive(SshConnection conn, long timeout)
throws SshTimeoutException, IOException {
SshClient client = SshClient.setUpDefaultClient();
try {
// Open the client
client.start();
// Connect to the server
ConnectFuture cf = client.connect(conn.getUsername(), conn.getHostname(), 22);
ClientSession session = cf.verify().getSession();
session.addPasswordIdentity(conn.getPassword());
session.auth().verify(TimeUnit.SECONDS.toMillis(timeout));
// Create the shell and channel its output/error streams
ChannelShell cs = session.createShellChannel();
cs.setOut(new NoCloseOutputStream(System.out));
cs.setErr(new NoCloseOutputStream(System.err));
cs.setIn(new NoCloseInputStream(System.in));
// Execute and wait
cs.open();
cs.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0);
cs.close(false);
session.close(false);
} finally {
client.stop();
}
}
public static void main(String[] args) throws Exception{
// String hostName = "192.168.11.100";
String hostName = "192.168.11.71";
String userName = "root";
String pwd = "password";
SshConnection conn = new SshConnection(userName,pwd,hostName);
// &&-表示前面命令执行成功在执行后面命令; ||表示前面命令执行失败了在执行后面命令; ";"表示一次执行两条命令
String cmd = "pwd && ps -ef|grep tomcat";
SshResponse response = runCommand(conn,cmd,15);
System.out.println("==error=>"+response.getErrOutput());
System.out.println("===return==>"+response.getReturnCode());
System.out.println("===stdOut===>"+response.getStdOutput());
// runCommandForInteractive(conn,15);
}
}
public class SshResponse {
private String stdOutput;
private String errOutput;
private int returnCode;
SshResponse(String stdOutput, String errOutput, int returnCode) {
this.stdOutput = stdOutput;
this.errOutput = errOutput;
this.returnCode = returnCode;
}
public String getStdOutput() {
return stdOutput;
}
public String getErrOutput() {
return errOutput;
}
public int getReturnCode() {
return returnCode;
}
}
public class SshConnection {
private String username;
private String password;
private String hostname;
public SshConnection(String username, String password, String hostname) {
this.username = username;
this.password = password;
this.hostname = hostname;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getHostname() {
return hostname;
}
}
//如果在非交互式模式发现command not found 这种错误
//建议在 命令行前面添加 source /etc/profile && source ~/.bash_profile && yourCommands
// /etc/profile-系统环境变量; ~/.bash_profile 当前用户环境变量, 根据你实际配置命令环境变量指定
maven pom 如下:
<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-core -->
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.8.0</version>
</dependency>
如果感觉对您有帮助,点个赞支持一下