【问题标题】:How to provide input selection in shell script when running though Java program?通过Java程序运行时如何在shell脚本中提供输入选择?
【发布时间】:2021-08-10 18:39:54
【问题描述】:

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

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

例如:

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

这里每个选项执行不同的操作,并且在选择任何要求进一步输入时。 例如:如果我选择选项 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();

【问题讨论】:

  • 嗨,有人可以帮忙吗?
  • 你想如何获取输入?图形用户界面?你的程序有什么定制的吗?标准输入(你的程序)?最后一种情况,你可以试试channel.setInputStream(System.in);
  • 您为什么要读取频道的输入流而不是写入
  • 顺便说一句,如果不是依赖于 myscript.sh 没有人,但你有,那会更好 minimal reproducible example,你执行类似 String[]{"bash", "-c", "read -p 'need input: ' input; echo \"got input: $input\""} 的东西——这样你的代码就不需要依赖它不包含。
  • 可能你不能,使用shell select创建一个交互式shell并保存stdin,你仍然试图用java粘回来,为什么?哈哈

标签: java shell unix automation


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    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的调用对于每个命令都是必需的。

    【讨论】:

      猜你喜欢
      • 2015-03-11
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多