当前位置: 首页 > 工具软件 > Apache SSHD > 使用案例 >

java 利用sshd-core 远程执行Linux shell命令

松智勇
2023-12-01

前面一篇文章写道利用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>

如果感觉对您有帮助,点个赞支持一下

 类似资料: