Несколько команд, использующих JSch

Мое требование заключается в следующем:
Я должен войти в систему Unix, используя мои учетные данные, и после входа в систему я должен сделать sudo другому пользователю. Как только sudo будет успешным, я должен вызвать shell в nohup. По завершении выполнения закройте канал и сессию.

Я попробовал первый шаг, который связан с использованием команды sudo, но я не знаю, как вызвать сценарий оболочки после команды sudo.

В приведенном ниже коде я могу выполнить команду sudo, но после получения доступа sudo, как я могу выполнить оболочку в nohup с пользователем masteruser, Так что для создания необходимых файлов моя оболочка имеет владельца как masteruser,

public class SSHUploader {

    Session session = null;

    public SSHUploader(){

    }

    public void connect(){
    try {

            JSch jsch = new JSch();
            session = jsch.getSession("user", "xxx.xxx.xx.xx", 22);
            session.setPassword("test");
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void executeCommand(String script) throws JSchException, IOException{
        System.out.println("Execute sudo");
        String sudo_pass = "test";
        ChannelExec channel = (ChannelExec) session.openChannel("exec");
        ((ChannelExec) channel).setCommand( script);

        InputStream in = channel.getInputStream();
        OutputStream out = channel.getOutputStream();
        ((ChannelExec) channel).setErrStream(System.err);

        channel.connect();
        out.write((sudo_pass + "\n").getBytes());
        out.flush();

        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) {
                System.out.println(ee);
            }
        }
        channel.disconnect();
        System.out.println("Sudo disconnect");
    }

    public void disconnect(){
        session.disconnect();
    }


    public static void main(String... args) throws JSchException, IOException {

        SSHUploader up = new SSHUploader();
        up.connect();

        up.executeCommand("sudo -u masteruser bash");

        up.disconnect();
    }

}

3 ответа

Для последовательного выполнения нескольких команд вы можете создать командную строку, как показано ниже:

String script ="pbrun su - user; cd /home/scripts;./sample_script.sh”

Выполните его и передайте эту строку вашему методу выше.

Сообщение может быть старым, но я нашел другой простой способ, который позволяет вам получать выходные данные каждой команды в отдельности. Обратите внимание, что этот код должен быть выполнен после открытия сеанса, как показано в примерах ( http://www.jcraft.com/jsch/examples/Exec.java.html):

for (String command : commands) {
            ChannelExec channel = (ChannelExec) session.openChannel("exec");
            channel.setInputStream(null);
            channel.setErrStream(System.err);
            channel.setCommand(command);
            channel.connect();
            printOutput(channel);
            channel.disconnect();
        }

куда printOutput использования channel.getInpuStream() прочитать результат команды.

Еще одно решение, которое я считаю элегантным, - использовать соединение из типаshellвместоexec. Но вам нужно будет дождаться появления правильного приглашения после каждой команды, как показано в следующем примере:

      public static void main(String[] args) throws Exception{
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    Session session = null;
    ChannelShell channel = null;
    try {
        JSch jsch = new JSch();
        session = jsch.getSession("username", "192.168.1.1", 22);
        session.setConfig(config);
        session.setPassword("password");
        session.connect();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        channel = (ChannelShell) session.openChannel("shell");
        channel.setOutputStream(outputStream);
        PrintStream stream = new PrintStream(channel.getOutputStream());
        channel.connect();

        stream.println("touch delme.txt");
        stream.flush();
        String response = waitForPrompt(outputStream, "$");
        System.out.println(response);

        stream.println("sudo chown root delme.txt");
        stream.flush();
        response = waitForPrompt(outputStream, ":");
        System.out.println(response);

        stream.println("mysecretrootpassword");
        stream.flush();
        response = waitForPrompt(outputStream, "$");
        System.out.println(response);


        stream.println("ls -la delme.txt");
        stream.flush();
        response = waitForPrompt(outputStream, "$");
        System.out.println(response);

    } finally {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }
}

static public String waitForPrompt(ByteArrayOutputStream outputStream, String prompt) throws Exception {
    int retries = NUMBER_OF_RETRIES;
    for (int x = 1; x < retries; x++) {
        TimeUnit.SECONDS.sleep(1);
        if (outputStream.toString().indexOf(prompt) > 0) {
            String responseString = outputStream.toString();
            outputStream.reset();
            return responseString;
        }
    }
    throw new Exception("Prompt failed to show after specified timeout");
}
Другие вопросы по тегам