Java JSch外壳通道在继续之前逐个执行命令测试结果

Java JSch外壳通道在继续之前逐个执行命令测试结果,java,ssh,jsch,Java,Ssh,Jsch,我有一个连接到SSH外壳的程序。我能够执行命令并从中读取输出 但我有一个新的要求。现在,如果成功执行下一个命令,我需要执行一个命令并读取输出 我使用了这个问题中的程序: 公共类SshConnectionManager{ 非公开静态会议; 专用静态信道; 私有静态字符串username=“”; 私有静态字符串密码=”; 私有静态字符串hostname=“”; 私有静态会话getSession(){ if(session==null | |!session.isConnected()){ 会话=连接

我有一个连接到SSH外壳的程序。我能够执行命令并从中读取输出

但我有一个新的要求。现在,如果成功执行下一个命令,我需要执行一个命令并读取输出

我使用了这个问题中的程序:

公共类SshConnectionManager{
非公开静态会议;
专用静态信道;
私有静态字符串username=“”;
私有静态字符串密码=”;
私有静态字符串hostname=“”;
私有静态会话getSession(){
if(session==null | |!session.isConnected()){
会话=连接(主机名、用户名、密码);
}
返回会议;
}
专用静态通道getChannel(){
if(channel==null | |!channel.isConnected()){
试一试{
channel=(ChannelShell)getSession().openChannel(“shell”);
通道设置(假);
channel.connect();
}捕获(例外e){
System.out.println(“打开通道时出错:+e”);
}
}
返回通道;
}
专用静态会话连接(字符串主机名、字符串用户名、字符串密码){
JSch JSch=新的JSch();
试一试{
session=jSch.getSession(用户名、主机名、22);
属性配置=新属性();
配置放置(“检查”、“否”);
session.setConfig(config);
session.setPassword(密码);
System.out.println(“将SSH连接到“+hostname+”-请等待几秒钟…”);
session.connect();
System.out.println(“已连接!”);
}捕获(例外e){
System.out.println(“连接到“+hostname+”:“+e”时出错);
}
返回会议;
}
私有静态void executeCommands(列表命令){
试一试{
Channel=getChannel();
System.out.println(“发送命令…”);
发送命令(通道、命令);
读通道输出(通道);
System.out.println(“发送命令完成!”);
}捕获(例外e){
System.out.println(“在执行命令时发生错误:”+e);
}
}
专用静态无效发送命令(通道、通道、列表命令){
试一试{
PrintStream out=新的PrintStream(channel.getOutputStream());
out.println(“#!/bin/bash”);
用于(字符串命令:命令){
out.println(命令);
}
out.println(“退出”);
out.flush();
}捕获(例外e){
System.out.println(“发送命令时出错:“+e”);
}
}
专用静态无效读通道输出(通道){
字节[]缓冲区=新字节[1024];
试一试{
InputStream in=channel.getInputStream();
字符串行=”;
while(true){
while(in.available()>0){
inti=in.read(缓冲区,0,1024);
if(i<0){
打破
}
行=新字符串(缓冲区,0,i);
系统输出打印项次(行);
}
如果(第行包含(“注销”)){
打破
}
if(channel.isClosed()){
打破
}
试一试{
睡眠(1000);
}捕获(异常ee){}
}
}捕获(例外e){
System.out.println(“读取通道输出时出错:+e”);
}
}
公共静态无效关闭(){
通道断开();
session.disconnect();
System.out.println(“断开的通道和会话”);
}
公共静态void main(字符串[]args){
List命令=new ArrayList();
命令。添加(“ls-l”);
executeCommands(命令);
close();
}
}
我需要使用“shell”通道而不是“exec”,因为服务器不允许使用“exec”通道:

通常,您应该为此使用“exec”频道。“shell”通道不应用于自动执行命令

但我知道您的服务器不支持“exec”频道。我为其他读者添加了上述评论,不是为了尝试使用此解决方案,除非他们真的必须这样做


正如@Yair-Harel已经评论的那样,如果你必须使用“shell”频道,你必须使用shell技术

因此,在您的特定情况下,您可能希望远程shell在命令完成后打印一些唯一的字符串和退出代码:

out.println(command + " ; echo Command-has-finished-with-code-$?");
然后继续读取输出,直到找到一行开头为“
”的命令以代码-”
结束。您分析退出代码并决定如何继续

请注意,命令语法(特别是命令分隔符
和退出代码变量
$?
)是特定于操作系统和shell的。由于您的服务器不是标准类型,因此语法可能会有所不同


旁注:

  • “#!/bin/bash”
    完全是胡说八道。shell忽略所有以
    #
    开头的命令(它是注释)。发送它没有意义
  • 不要使用StrichostKeyChecking=no。看
out.println(command + " ; echo Command-has-finished-with-code-$?");