如何使用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"。