Sending commands to server via JSch shell channel

后端 未结 9 849
渐次进展
渐次进展 2020-11-30 03:37

I can\'t figure it out how I can send commands via JSch shell channel.

I do this, but it doesn\'t work:

JSch shell = new JSch();
String command = \"c         


        
相关标签:
9条回答
  • 2020-11-30 03:45

    try this

    Channel channel=session.openChannel("shell");
                OutputStream ops = channel.getOutputStream();
            PrintStream ps = new PrintStream(ops, true);
    
             channel.connect();
             ps.println("mkdir folder"); 
             ps.println("dir");
     //give commands to be executed inside println.and can have any no of commands sent.
                          ps.close();
    
             InputStream in=channel.getInputStream();
             byte[] bt=new byte[1024];
    
    
             while(true)
             {
    
             while(in.available()>0)
             {
             int i=in.read(bt, 0, 1024);
             if(i<0)
              break;
                String str=new String(bt, 0, i);
              //displays the output of the command executed.
                System.out.print(str);
    
    
             }
             if(channel.isClosed())
             {
    
                 break;
            }
             Thread.sleep(1000);
             channel.disconnect();
             session.disconnect();   
             }
    
    0 讨论(0)
  • 2020-11-30 03:46

    Following was a quickly written code for my assignment. Not a well done program. But serves its purpose.

    1. Connects via SSH (using Jsch) to a server (using a Private Key File - mykey.pem)
    2. Creates a shell script (to mount a volume and mkfs)
    3. Runs on the remote machine
    4. All the while you can see the output on your stdout

    The code follows:

    public class connectSSH {
    
    public void connect(String dnsName, String privKey) throws IOException {
        JSch jSch = new JSch();
    
        try {
    
                        //Authenticate through Private Key File
            jSch.addIdentity(privKey);
                        //Give the user and dnsName
            Session session = jSch.getSession("root", dnsName, 22);
                        //Required if not a trusted host
            java.util.Properties config = new java.util.Properties(); 
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            System.out.println("Connecting SSH to " + dnsName + " - Please wait for few minutes... ");
            session.connect();
                //Open a shell 
            Channel channel=session.openChannel("shell");
            channel.setOutputStream(System.out);
                //Create a Shell Script
            File shellScript = createShellScript();
                //Convert the shell script to byte stream
            FileInputStream fin = new FileInputStream(shellScript);
            byte fileContent[] = new byte[(int)shellScript.length()];
            fin.read(fileContent);
            InputStream in = new ByteArrayInputStream(fileContent);
                //Set the shell script to the channel as input stream
            channel.setInputStream(in);
                //Connect and have fun!
            channel.connect();          
    
        } catch (JSchException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    }
    
    public File createShellScript() {
         String filename = "shellscript.sh";
         File fstream = new File(filename);
    
         try{
              // Create file 
             PrintStream out = new PrintStream(new FileOutputStream(fstream));
             out.println("#!/bin/bash");
             out.println("echo \"hi\" > /tmp/test.info");
             out.println("echo \"n\" > /tmp/fdisk.in");
             out.println("echo \"p\" >> /tmp/fdisk.in");
             out.println("echo \"1\" >> /tmp/fdisk.in");
             out.println("echo >> /tmp/fdisk.in");
             out.println("echo >> /tmp/fdisk.in");
             out.println("echo \"w\" >> /tmp/fdisk.in");
    
             out.println("/sbin/fdisk /dev/sdf < /tmp/fdisk.in");
             out.println("mkfs.ext3 /dev/sdf1");
             out.println("mkdir /usr/myebs");
             out.println("mount /dev/sdf1 /usr/myebs");
             out.println("partprobe /dev/sdf1");
    
             out.println("echo \"Success\"");
    
             //Close the output stream
             out.close();
         }catch (Exception e){//Catch exception if any
             System.err.println("Error: " + e.getMessage());
         }
         return fstream;
    
    }
    
    public static void main(String[] args) {
        connectSSH ssh = new connectSSH();
        String privKey = "/Users/neo/Desktop/mykey.pem";
        try {
            ssh.connect("yourexampleserver.com", privKey);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    }
    
    }
    
    0 讨论(0)
  • 2020-11-30 03:48
    private void executeRemoteCommandAsSudo(String sudoAs, String password,
                String command, int delayInSeconds) 
    {
        logger.info("executeRemoteCommandAsSudo started....");
        logger.info("sudoAs=" + sudoAs);
        logger.info("command=" + command);
        logger.info("delayInSeconds=" + delayInSeconds);
        Session session = null;
        Channel channel = null;
        try {
            session = getSession();
            channel = session.openChannel("exec");
            String sudoCommand = "sudo su - " + sudoAs;
            ((ChannelExec) channel).setCommand(sudoCommand);
            ((ChannelExec) channel).setPty(true);
            channel.connect();
            InputStream inputStream = channel.getInputStream();
            OutputStream out = channel.getOutputStream();
            ((ChannelExec) channel).setErrStream(System.err);
            out.write((password + "\n").getBytes());
            out.flush();
            Thread.sleep(1000);
            out.write((command + "\n").getBytes());
            out.flush();
            Thread.sleep(1000 * delayInSeconds);
            out.write(("logout" + "\n").getBytes());
            out.flush();
            Thread.sleep(1000);
            logInfo(channel, inputStream);
            out.write(("exit" + "\n").getBytes());
            out.flush();
            out.close();
            Thread.sleep(1000);
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        } finally {
            session.disconnect();
            channel.disconnect();
        }
        logger.info("executeRemoteCommandAsSudo completed....");
    }
    private void logInfo(Channel channel, InputStream in) 
    {
        try {
            byte[] tmp = new byte[1024];
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0)
                        break;
                    logger.info(new String(tmp, 0, i));
                }
                if (channel.isClosed()) {
                    logger.info("exit-status: " + channel.getExitStatus());
                    break;
                }
            }
        } catch (Exception ex) {
            logger.error(ex);
        }
    }
    
    private Session getSession() throws JSchException 
    {
        JSch jsch = new JSch();
        logger.info("ftpUser=" + ftpUser);
        logger.info("ftpHost=" + ftpHost);
        Session session = jsch.getSession(ftpUser, ftpHost, 22);
        session.setPassword(ftpPassword);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
        return session;
    }
    
    0 讨论(0)
  • 2020-11-30 03:57

    If it hangs at readLine() that means either your "while" is never ending (might be unlikely considering your code), or, readLine() is waiting for its source, namely the IOstream blocks the thread cause available()!=true.

    I can't quite troubleshoot your code without seeing your debug info. But as an advice, have you tried PipedIntputStream? The idea is to pipe your console input to "your" output so that you can "write" it. To implement this, you need to initialize the in/out-put.

    InputStream in = new PipedInputStream();
    PipedOutputStream pin = new PipedOutputStream((PipedInputStream) in);
    /**...*/
    channel.setInputStream(in);
    channel.connect();
    /** ...*/
    pin.write(myScript.getBytes());
    

    The same goes to your question, how to read console output.

    PipedInputStream pout = new PipedInputStream((PipedOutputStream) out);
    /**
    * ...
    */
    BufferedReader consoleOutput = new BufferedReader(new InputStreamReader(pout));
    consoleOutput.readLine();
    

    And again, if you are not sure how many lines to read and thus want to use "while", make sure you do something inside while to prevent 1) busy-waiting 2) ending-condition. Example:

    while(!end)
    {
       consoleOutput.mark(32);
       if (consoleOutput.read()==0x03) end = true;//End of Text
       else
       { 
         consoleOutput.reset();
         consoleOutput.readLine();
         end = false;
       }
    }
    
    0 讨论(0)
  • 2020-11-30 03:59

    Try this:

    JSch jsch = new JSch();
    
    try
    {
      Session session = jsch.getSession("root", "192.168.0.1", 22);
      java.util.Properties config = new java.util.Properties();
      config.put("StrictHostKeyChecking", "no");
      session.setConfig(config);
    
      session.connect();
    
      String command = "lsof -i :80";
      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;
          System.out.print(new String(tmp, 0, i));
        }
        if (channel.isClosed())
        {
          System.out.println("exit-status: " + channel.getExitStatus());
          break;
        }
        try
        {
          Thread.sleep(1000);
        }
        catch (Exception ee)
        {
        }
      }
    
      channel.disconnect();
      session.disconnect();
    }
    catch (Exception e)
    {
      System.out.println(e.getMessage());
    }
    
    0 讨论(0)
  • 2020-11-30 04:01

    Usage:

    String remoteCommandOutput = exec("ssh://user:pass@host/work/dir/path", "ls -t | head -n1");
    String remoteShellOutput = shell("ssh://user:pass@host/work/dir/path", "ls")
    shell("ssh://user:pass@host/work/dir/path", "ls", System.out)
    shell("ssh://user:pass@host", System.in, System.out);
    

    Implementation

    0 讨论(0)
提交回复
热议问题