Pre Merge pull request !1379 from 肆风/v7-dev

This commit is contained in:
肆风
2025-09-09 03:52:56 +00:00
committed by Gitee

View File

@@ -16,6 +16,7 @@
package cn.hutool.v7.extra.ssh.engine.jsch;
import cn.hutool.v7.core.thread.ThreadUtil;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelShell;
@@ -28,11 +29,13 @@ import cn.hutool.v7.extra.ssh.Connector;
import cn.hutool.v7.extra.ssh.Session;
import cn.hutool.v7.extra.ssh.SshException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Jsch Session封装
@@ -202,6 +205,77 @@ public class JschSession implements Session {
}
}
/**
* 执行Shell命令
*
* @param cmd 命令
* @param charset 发送和读取内容的编码
* @return {@link String}
*/
public String execSync(final String cmd, final Charset charset) {
return execSync(cmd, charset, System.err);
}
/**
* 执行Shell命令使用EXEC方式
* <p>
* 此方法单次发送一个命令到服务端不读取环境变量执行结束后自动关闭channel会阻塞直到命令执行完毕命令执行错误会抛出异常。
* </p>
*
* @param cmd 命令
* @param charset 发送和读取内容的编码
* @param errStream 错误信息输出到的位置
* @return 执行结果内容
* @since 4.3.1
*/
public String execSync(final String cmd, Charset charset, final OutputStream errStream) {
if (null == charset) {
charset = CharsetUtil.UTF_8;
}
final ChannelExec channel = (ChannelExec) createChannel(ChannelType.EXEC);
channel.setCommand(ByteUtil.toBytes(cmd, charset));
channel.setInputStream(null);
channel.setErrStream(errStream);
InputStream in = null;
ByteArrayOutputStream realtimeOutput = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
try {
channel.connect();
in = channel.getInputStream();
while (!channel.isClosed()) {
if (in.available() > 0) {
int len = in.read(buffer);
if (len > 0) {
realtimeOutput.write(buffer, 0, len); // 写入本地缓冲区
}
}
ThreadUtil.sleep(100);
}
if (in.available() > 0) {
int len = in.read(buffer);
if (len > 0) {
realtimeOutput.write(buffer, 0, len);
}
}
int exitStatus = channel.getExitStatus();
if(exitStatus != 0){
String errorMsg = errStream.toString().trim();
throw new SshException(errorMsg);
}
return realtimeOutput.toString(StandardCharsets.UTF_8.name()).trim();
} catch (final IOException e) {
throw new IORuntimeException(e);
} catch (final JSchException e) {
throw new SshException(e);
} finally {
IoUtil.closeQuietly(in);
if (channel.isConnected()) {
channel.disconnect();
}
}
}
/**
* 执行Shell命令
* <p>