当 运行 虽然 Java 程序时,如何在 shell 脚本中提供输入选择?

How to provide input selection in shell script when running though Java program?

在我的 Java 程序中,我想做的是:

首先,我连接到 Unix 服务器并执行一个 shell 脚本。但是在该 shell 脚本中,您必须 select 选项才能在 selected 选项后执行不同的操作。

例如:

Please select from below menu options
1. Create directory and subdirectory
2. Copy files
3. Update paths
4. Press 9 to exit

此处每个选项执行不同的操作,并且在 selecting 时任何要求进一步输入。 例如:如果我 select 一个选项 1 它将询问路径:

Please enter the path where you want to create a directory

现在我的问题是:如何在运行这个来自Java代码的shell脚本的同时输入这个输入?

以下代码用于连接到 unix 服务器并执行 shell 脚本:

JSch jsch = new JSch();

String command = "/tmp/myscript.sh";
Session session = jsch.getSession(user, host, 22);
session.connect();

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

channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
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()) {
      if (channel.getExitStatus() == 0) {
          System.out.println("Command executed successully.");
      }
      break;
  }
}
channel.disconnect();
session.disconnect();

您可以在 shell 脚本中打印到 /dev/tty 并从 /dev/tty 读取。像这样包装 /tmp/myscript.sh

#!/bin/bash
(
ORIGINAL_CODE_HERE
) < /dev/tty > /dev/tty

假设我们要“创建目录和子目录”,然后退出。
频道准备就绪后,我们必须:

  1. 发送创建命令“1”
  2. 发送路径“/path/to/directory”
  3. 发送退出命令“9”
JSch jsch = new JSch();

String command = "/tmp/myscript.sh";
Session session = jsch.getSession(user, host, 22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(passwd);
session.connect();

ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
channel.setInputStream(null);
channel.setErrStream(System.err);
InputStream is = channel.getInputStream();
// We will send commands through this stream
OutputStream os = channel.getOutputStream();
channel.connect();

int step = 1;
byte[] tmp = new byte[1024];
int read;
while (true) {
    // Wait for available data
    while(is.available() == 0) {
        Thread.sleep(100);
    }
    // Read the script/command output
    while(is.available() > 0) {
        read = is.read(tmp);
        if (read < 0) {
            break;
        }
        System.out.print(new String(tmp, 0, read));
    }
    // Send a command depending on current step
    switch(step) {
    case 1:
        // 1. Create directory command
        os.write("1\n".getBytes());
        os.flush();
        break;
    case 2:
        // 2. Path to create
        os.write("/path/to/directory\n".getBytes());
        os.flush();
        break;
    case 3:
        // 3. Exit command
        os.write("9\n".getBytes());
        os.flush();
        break;
    }
    step++;
    if (channel.isClosed()) {
        if (channel.getExitStatus() == 0) {
            System.out.println("Command executed successully.");
        }
        break;
    }
}
channel.disconnect();
session.disconnect();

最后的“\n”和对 os.flush 的调用对于每个命令都是强制性的。