Jsch实践(三):如何使用Jsch的ChannelShell类,在远程服务器上执行脚本命令?

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