JSch Channel.getExitStatus 没有 return 在 "shell" 通道中执行的命令的状态
JSch Channel.getExitStatus does not return status of command executed in "shell" channel
我正在尝试通过 JSch – diff
命令比较文件。
我想通过 Java 代码获取状态以了解文件是否等于,即 echo $status
。
我怎样才能在 java 中做到这一点?
这是我的 class 到 运行 SSH 命令
public class SSH {
static Logger logger = LogManager.getLogger("sshLogger");
static Process p;
static String s;
int exitStatus = -1;
String user;
String pass;
String server;
String command;
public Channel channel;
public Session session;
public InputStream in;
public SSH(String user, String pass, String server) {
this.user = user;
this.pass = pass;
this.server = server;
logger.debug("instance: " + user + "@" + server);
}
private Session getConnectedSession(String user, String pass, String server) throws JSchException {
session = new JSch().getSession(user, server, 22);
java.util.Properties config = new java.util.Properties();
session.setPassword(pass);
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications","publickey,keyboard-interactive,password");
session.setConfig(config);
logger.debug("get connected session at: " + server);
session.connect();
logger.debug("connected to session");
return session;
}
public Channel getChannel() {
// ByteArrayOutputStream byteArrOutSt = new ByteArrayOutputStream();
try {
session = getConnectedSession(user, pass, server);
logger.debug("opening channel at: " + server);
channel = session.openChannel("shell");
} catch (JSchException e) {
logger.error("failed to connect to: "+ user + "@"+ server);
e.printStackTrace();
}
// channel.setOutputStream(baos);
channel.setOutputStream(System.out);
channel.setExtOutputStream(System.out, true);
// channel.setPty(Boolean.FALSE);
return channel;
}
public String commandBuilder(String... commands) {
StringBuilder commandString = new StringBuilder();
for (String command : commands) {
logger.debug("adding command: " + command);
commandString.append(command + "\n");
}
logger.debug("adding command: exit");
commandString.append("exit\n");
String myCommand = commandString.toString().replace("\n", "\n");
return myCommand;
}
public String executeCommand(String myCommand) {
channel = getChannel();
//String finishedCommand = commandBuilder(myCommand);
logger.debug(myCommand);
StringBuilder outBuff = new StringBuilder();
String outComm = null;
channel.setInputStream(new ByteArrayInputStream(myCommand.getBytes(StandardCharsets.UTF_8)));
try {
in = channel.getInputStream();
channel.connect();
// read from the output
System.out.println("printing");
while (true) {
for (int c; ((c = in.read()) >= 0);) {
outBuff.append((char) c);
}
if (channel.isClosed()) {
if (in.available() > 0)
continue;
exitStatus = channel.getExitStatus();
break;
}
}
} catch (IOException e) {
logger.error("failed while running or reading output of command: " + myCommand);
} catch (JSchException e) {
logger.error("failed to connect to server while running command: " + myCommand);
}
logger.info(outBuff.toString());
return outBuff.toString();
}
public void endSession() {
logger.debug("ending session");
channel.disconnect();
session.disconnect();
logger.debug("disconnected channel and session");
// print exit status
logger.debug("Exit status of the execution: " + exitStatus);
if (exitStatus == 0) {
logger.debug(" (OK)\n");
} else {
logger.debug(" (NOK)\n");
}
}
public String runCommand(String... commands) {
// many commands as you want
String output = null;
String myCommands;
myCommands = commandBuilder(commands);
try {
output = executeCommand(myCommands);
endSession();
} catch (Exception e) {
logger.error("failed to run ssh comands: "+ commands);
e.printStackTrace();
}
return output;
}
}
为 diff
使用 SSH 示例:
SSH session = new SSH(user, pass, server);
session.runCommand("diff file1.xml file2.xml");
首先不要执行“shell”频道中的命令。 “shell”是一个只有输入和输出的黑盒子。参见 What is the difference between the 'shell' channel and the 'exec' channel in JSch
使用“exec”频道。在“exec”频道中,Channel.getExitStatus
有效。
有关代码示例,请参阅:How to read JSch command output?
强制警告:不要使用StrictHostKeyChecking=no
盲目接受所有主机密钥。这是一个安全漏洞。您失去了针对 MITM attacks. For the correct (and secure) approach, see:
的保护
我正在尝试通过 JSch – diff
命令比较文件。
我想通过 Java 代码获取状态以了解文件是否等于,即 echo $status
。
我怎样才能在 java 中做到这一点?
这是我的 class 到 运行 SSH 命令
public class SSH {
static Logger logger = LogManager.getLogger("sshLogger");
static Process p;
static String s;
int exitStatus = -1;
String user;
String pass;
String server;
String command;
public Channel channel;
public Session session;
public InputStream in;
public SSH(String user, String pass, String server) {
this.user = user;
this.pass = pass;
this.server = server;
logger.debug("instance: " + user + "@" + server);
}
private Session getConnectedSession(String user, String pass, String server) throws JSchException {
session = new JSch().getSession(user, server, 22);
java.util.Properties config = new java.util.Properties();
session.setPassword(pass);
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications","publickey,keyboard-interactive,password");
session.setConfig(config);
logger.debug("get connected session at: " + server);
session.connect();
logger.debug("connected to session");
return session;
}
public Channel getChannel() {
// ByteArrayOutputStream byteArrOutSt = new ByteArrayOutputStream();
try {
session = getConnectedSession(user, pass, server);
logger.debug("opening channel at: " + server);
channel = session.openChannel("shell");
} catch (JSchException e) {
logger.error("failed to connect to: "+ user + "@"+ server);
e.printStackTrace();
}
// channel.setOutputStream(baos);
channel.setOutputStream(System.out);
channel.setExtOutputStream(System.out, true);
// channel.setPty(Boolean.FALSE);
return channel;
}
public String commandBuilder(String... commands) {
StringBuilder commandString = new StringBuilder();
for (String command : commands) {
logger.debug("adding command: " + command);
commandString.append(command + "\n");
}
logger.debug("adding command: exit");
commandString.append("exit\n");
String myCommand = commandString.toString().replace("\n", "\n");
return myCommand;
}
public String executeCommand(String myCommand) {
channel = getChannel();
//String finishedCommand = commandBuilder(myCommand);
logger.debug(myCommand);
StringBuilder outBuff = new StringBuilder();
String outComm = null;
channel.setInputStream(new ByteArrayInputStream(myCommand.getBytes(StandardCharsets.UTF_8)));
try {
in = channel.getInputStream();
channel.connect();
// read from the output
System.out.println("printing");
while (true) {
for (int c; ((c = in.read()) >= 0);) {
outBuff.append((char) c);
}
if (channel.isClosed()) {
if (in.available() > 0)
continue;
exitStatus = channel.getExitStatus();
break;
}
}
} catch (IOException e) {
logger.error("failed while running or reading output of command: " + myCommand);
} catch (JSchException e) {
logger.error("failed to connect to server while running command: " + myCommand);
}
logger.info(outBuff.toString());
return outBuff.toString();
}
public void endSession() {
logger.debug("ending session");
channel.disconnect();
session.disconnect();
logger.debug("disconnected channel and session");
// print exit status
logger.debug("Exit status of the execution: " + exitStatus);
if (exitStatus == 0) {
logger.debug(" (OK)\n");
} else {
logger.debug(" (NOK)\n");
}
}
public String runCommand(String... commands) {
// many commands as you want
String output = null;
String myCommands;
myCommands = commandBuilder(commands);
try {
output = executeCommand(myCommands);
endSession();
} catch (Exception e) {
logger.error("failed to run ssh comands: "+ commands);
e.printStackTrace();
}
return output;
}
}
为 diff
使用 SSH 示例:
SSH session = new SSH(user, pass, server);
session.runCommand("diff file1.xml file2.xml");
首先不要执行“shell”频道中的命令。 “shell”是一个只有输入和输出的黑盒子。参见 What is the difference between the 'shell' channel and the 'exec' channel in JSch
使用“exec”频道。在“exec”频道中,Channel.getExitStatus
有效。
有关代码示例,请参阅:How to read JSch command output?
强制警告:不要使用StrictHostKeyChecking=no
盲目接受所有主机密钥。这是一个安全漏洞。您失去了针对 MITM attacks. For the correct (and secure) approach, see: