Java JSch - анализ входных данных для запуска программы Perl в Linux

Что я хочу сделать:

  1. Подключиться к серверу Linux через JSch

  2. Используйте ChannelExec для выполнения сценария Perl

  3. Пока Perl-скрипт запущен, он запрашивает ввод. Предоставьте этот ввод

Шаги 1 и 2 завершены, но я не смог найти ответ на шаг 3. Программа останавливается и ожидает некоторого ввода, но я не знаю, как вставить этот ввод в ожидающий сценарий Perl.

Вот мой код:

package test_jar;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class SSH_Connection {

    private static Session session         = null;
    private static ChannelSftp channelsftp = null;
    private static Channel channelexec     = null;
    private static List<String> commands   = new ArrayList<String>();

    public static void main(String[] args) {

        int res = sftp_connect("xx.xxx.xx.xx", 22, "user", "password");

        if ( res != -1 ) {
            commands.add("/home/hello.pl");
            execCommands();
        }
    }

    private static String build_commandString(List<String> commandlist) {
        String cmdstring = "";

        for ( String command: commandlist ) {

            if ( ! cmdstring.equals("") ) {
                cmdstring += "; ";
            }

            cmdstring += command;
        }

        return cmdstring;
    }

    public static int sftp_connect(String ip, int port, String user, String pw){        
        try {
            JSch JavaSecureChannel = new JSch();

            session = JavaSecureChannel.getSession(user, ip, port);
            session.setPassword(pw);

            //just for testing StrictHostKeyChecking = no
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            //Building SFTP Connection
            channelsftp = (ChannelSftp) session.openChannel("sftp");
            channelsftp.connect();
            channelexec = session.openChannel("exec");

            return 0;
        }
        catch(Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    public static void execCommands() {

        //check if there are commands to exec
        if ( ! commands.isEmpty() ) {

            try {
                System.out.println(build_commandString(commands));
                ((ChannelExec)channelexec).setCommand(build_commandString(commands));
                channelexec.setInputStream(null);
                ((ChannelExec)channelexec).setErrStream(System.err);

                InputStream in = channelexec.getInputStream();
                channelexec.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 ( channelexec.isClosed() ) {
                        System.out.println("exit-status: "+channelexec.getExitStatus());
                        break;
                    }

                    try {
                        Thread.sleep(1000);
                    }
                    catch(Exception ee) {
                    }
                }

                channelexec.disconnect();
                System.out.println("DONE");
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
}

А это мой сценарий Perl:

#!/usr/bin/perl -w
# Hello World Program in Perl
#

print "Hello World!\n";

print "Pls enter user:\n";
my $input = <STDIN>;

print "You entered: $input";

print "Hello World2!\n";

ОБНОВИТЬ

Я нашел решение. Благодаря Nickmarkham я поискал документацию по .getOutputStream() и нашел это решение:

//channelexec.setInputStream(null);

OutputStream inputstream_for_the_channel = channelexec.getOutputStream();
PrintStream commander = new PrintStream(inputstream_for_the_channel, true);

//Connect to Exec Channel
channelexec.connect();

//inputs for the running script
commander.println("input1");
commander.println("input2");
commander.close();
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
101
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вам нужно что-то вроде:

Writer writer = new BufferedWriter(new OutputStreamWriter(channelexec.getOutputStream()));
writer.write("this is the input to the script\n");

конечно, с правильной обработкой ошибок и очисткой. :)

Вам также необходимо удалить эту строку:

channelexec.setInputStream(null);

на основе документов API, которые я нашел на https://epaul.github.io/jsch-documentation/javadoc/

Спасибо за ответ, но я получаю сообщение об ошибке: метод OutputStreamWriter (OutputStream) не определен для типа SSH_Connection

Panderas 08.05.2018 15:24

Упс… не учел "новый".

NickMarkham 08.05.2018 21:48

Другие вопросы по теме