如何使用Jsch的ChannelShell类,在远程服务器上执行脚本命令
要使用JSch的ChannelShell类在远程服务器上执行脚本命令,你需要创建一个shell通道,然后向这个通道的输入流发送命令,并读取输出流来获取命令的响应。下面是一个示例代码,展示了如何使用ChannelShell类在远程服务器上执行脚本命令
import com.jcraft.jsch.*; import java.io.InputStream;
import java.io.OutputStream; public class JschExecuteRemoteCommandWithShell { public static void main(String[] args) { String host = "your.remote.host"; int port = 22; String user = "your_username"; String password = "your_password"; JSch jsch = new JSch(); Session session = null; ChannelShell channelShell = null; InputStream in = null; OutputStream out = null; try { session = jsch.getSession(user, host, port); session.setPassword(password); // 配置 session 属性 java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); // 生产环境中应该验证主机密钥 session.setConfig(config); // 连接到服务器 session.connect(); // 打开 shell 通道 channelShell = (ChannelShell) session.openChannel("shell"); // 获取输入、输出流 in = channelShell.getInputStream(); out = channelShell.getOutputStream(); // 连接通道 channelShell.connect(); // 发送命令到远程 shell out.write(("cd /path/to/directory\n").getBytes()); // 切换到指定目录 out.write(("./your_script.sh\n").getBytes()); // 执行脚本 out.write("exit\n".getBytes()); // 退出 shell out.flush(); // 刷新输出流 // 读取命令输出 byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; System.out.print(new String(tmp, 0, i)); } if (channelShell.isClosed()) { System.out.println("Exit status: " + channelShell.getExitStatus()); break; } try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } // 断开通道连接 channelShell.disconnect(); } catch (JSchException | IOException e) { e.printStackTrace(); } finally { // 关闭流和会话 if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if (channelShell != null) { channelShell.disconnect(); } if (session != null) { session.disconnect(); } } }
}
在这个示例中,我们首先创建了一个ChannelShell对象,并连接到远程服务器的shell。然后,我们获取了输入和输出流,并使用输出流向远程shell发送命令。这里我们发送了两个命令:cd /path/to/directory来改变当前目录,./your_script.sh来执行脚本。发送完命令后,我们通过调用out.flush()来确保所有命令都被发送到远程服务器。
之后,我们使用输入流来读取远程shell的输出。我们持续读取输出,直到shell通道关闭。最后,我们断开了通道和会话的连接,并关闭了所有的流。
请注意:
你需要替换示例代码中的your.remote.host、your_username、your_password、/path/to/directory和your_script.sh为实际的值。此外,StrictHostKeyChecking设置为"no"在生产环境中是不安全的,你应该使用一个已知的host key或者将远程主机的公钥添加到你的known_hosts文件中,然后将StrictHostKeyChecking设置为"yes"。