使用 JSch 的特定命令输出来触发下一个命令

Using specific command output of JSch to trigger next command

使用以下代码:

public static void main(String[] args) throws Exception
{
  JSch jsch = new JSch();
  String user = "XXXXX";       
  String host = "XXXXX"; 
  String passwd = "XXXXX";      
  int port = 22;    
  Session session = jsch.getSession(user, host, port);
  session.setPassword(passwd);
  session.setConfig("StrictHostKeyChecking", "no");
  session.setConfig("PreferredAuthentications","publickey,keyboard-interactive,password");
  session.connect();

  Channel channel = session.openChannel("shell");
  OutputStream ops = channel.getOutputStream();
  PrintStream ps = new PrintStream(ops, true);

  channel.connect();

  //commands
  ps.println("sudo su - user");
  ps.println("ls | wc -l");

  ps.println("pwd");

  ps.println("exit");
  ps.close();

  channel.disconnect();
  session.disconnect();
 }  

对于这种代码,是否可以:

  1. 分别获取在控制台上触发的每个命令的输出。
  2. 根据之前的输出使用控制语句。

例如:如果我使用

ls | wc -l

输出将是一个固定数字,因为根目录不会改变。使用此数字使用 if/else 条件处理步骤 a 或 b。

我不久前写了这篇文章,但我做的与您的设置方式略有不同。它抓住了 returns 你想要的一切。

编辑:我更新了代码,因此可以很容易地实用地设置用户名、主机和密码。然后循环遍历一组命令,检查 return 是否能够执行另一个命令或继续。

这是带有一些额外注释的代码(希望对您有所帮助)

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import java.io.InputStream;
import java.util.Scanner;
import java.util.Properties;

public class cmdExec
{
  public static void main(String[] arg)
  {
    try
    {
      JSch jsch = new JSch();

      String user = "<username>";
      String host = "<host>";
      String paswrd = "<password>";

      Session session = jsch.getSession(user, host, 22);

      Properties config = new Properties();
      config.put("StrictHostKeyChecking", "no");

      session.setPassword(paswrd);

      session.setConfig(config);
      session.connect();

      // build an array of commands to run
      String[] cmds = {"user | wc -l", "ps -ef | wc -l"};

      for(int cnt = 0; cnt < cmds.length; cnt++)
      {
        String command = cmds[cnt];

        Channel channel = session.openChannel("exec");
        ((ChannelExec)channel).setCommand(command);

        channel.setInputStream(null);

        ((ChannelExec)channel).setErrStream(System.err);

        InputStream in = channel.getInputStream();

        channel.connect();

        byte[] tmp = new byte[1024];

        while (true){

            while (in.available()>0){
              int i = in.read(tmp, 0, 1024);
              if (i < 0)
              {
                break;
              }
              // grab the return, hopefully a number
              String strRet = new String(tmp, 0, i);
              // trim whitespace and convert to int
              int ret = Integer.parseInt(strRet.trim());

              if ( ret != 1 )
              {
                System.out.println("Do something else, the return wasn't one.");
              }
              else
              {
                System.out.println("Return was 1. Continuing on...");
              }
            }
            if(channel.isClosed()){
              if(in.available()>0) continue;
              //System.out.println("exit-status: "+channel.getExitStatus());
              break;
            }
            try
            {
              Thread.sleep(1000);
            }
            catch (Exception ee)
            {
              // Do something with the exception
            }  
        }
        channel.disconnect();

      }
    }
    catch(Exception e){
      System.out.println(e);
    }
  }
}