2012-03-29 1 views
6

Мне интересно, есть ли способ выполнить следующий сценарий оболочки, который ждет ввода пользователя с использованием класса Runtime java?Как выполнить интерактивный сценарий оболочки с использованием java Runtime?

#!/bin/bash 

echo "Please enter your name:" 
read name 
echo "Welcome $name" 

Я использую следующий код java для выполнения этой задачи, но он просто показывает пустую консоль.

public class TestShellScript { 
public static void main(String[] args) { 

     File wd = new File("/mnt/client/"); 
      System.out.println("Working Directory: " +wd); 
      Process proc = null; 

      try { 
       proc = Runtime.getRuntime().exec("sudo ./test.sh", null, wd); 

      } catch (Exception e) { 
      e.printStackTrace(); 
      } 


} 

}

Thing, когда я исполню над программой, я полагал, что это будет выполняться скрипт, и что скрипт будет ждать ввода пользователя, но он просто печатает текущий каталог, а затем завершает свою работу. Есть ли способ сделать это, или это невозможно вообще в java?

Заранее спасибо

+0

http://stackoverflow.com/questions/4784789/call-interactive -perl-script-from-java –

ответ

1

Причина она печатает текущую директорию и выходит потому, что ваши выходы Java приложения. Вам нужно добавить (резьбовую) слушателя к входным и ошибок потоков вашего созданного процесса, и вы, вероятно, хотите добавить PrintStream в выходной поток процесса в

пример:



      proc = Runtime.getRuntime().exec(cmds); 
      PrintStream pw = new PrintStream(proc.getOutputStream()); 
      FetcherListener fl = new FetcherListener() { 

       @Override 
       public void fetchedMore(byte[] buf, int start, int end) { 
        textOut.println(new String(buf, start, end - start)); 
       } 

       @Override 
       public void fetchedAll(byte[] buf) { 
       }   
      }; 
      IOUtils.loadDataASync(proc.getInputStream(), fl); 
      IOUtils.loadDataASync(proc.getErrorStream(), fl); 
      String home = System.getProperty("user.home"); 
      //System.out.println("home: " + home); 
      String profile = IOUtils.loadTextFile(new File(home + "/.profile")); 
      pw.println(profile); 
      pw.flush(); 

Для запуска вам понадобится загрузить проект sourceforge: http://tus.sourceforge.net/, но, надеюсь, фрагмент кода достаточно поучителен, чтобы вы могли просто адаптироваться к J2SE и тому, что вы используете.

+0

Можете ли вы опубликовать какой-либо пример кода или ссылку на веб-страницу, объясняющую это с помощью примера в деталях. –

+0

вот какой код, который демонстрирует: – ControlAltDel

+0

Я пробовал с вашим кодом и загружал ваш источник из SVN, что происходит, он ждет ввода, а также я могу вводить ввод на консоли, но он никогда не передает этот ввод в сценарий оболочки и программы. при выполнении. В идеале, как он должен себя вести, после ввода сценария оболочки имени должен печатать имя и программа должна выполняться. –

1

Если вы используете Java ProcessBuilder, вы должны иметь возможность получать потоки ввода, ошибки и вывода процесса, который вы создаете.

Эти потоки могут использоваться для получения информации, выходящей из процесса (например, запросов для ввода), но они также могут быть записаны для непосредственного ввода информации в процесс. Например:

InputStream stdout = process.getInputStream(); 
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout)); 

String line; 
while(true){ 
    line = reader.readLine(); 
    //... 

Это даст вам результат непосредственно процесса. Я не делал этого сам, но я уверен, что process.getOutputStream() дает вам что-то, что может быть написано напрямую для отправки ввода в процесс.

1

Проблема с запуском интерактивных программ, таких как sudo, от Runtime.exec заключается в том, что он прикрепляет их stdin и stdout к трубам, а не к консольному устройству, в котором они нуждаются. Вы можете заставить его работать redirecting the input and output to /dev/tty.

Вы можете добиться такого же поведения, используя новый класс ProcessBuilder, настроив перенаправление с помощью ProcessBuilder.Redirect.INHERIT.

0

Обратите внимание, что вы можете отправлять входные данные в свой скрипт с Java. Тем не менее, я очень сильно рекомендую взглянуть на Commons Exec, если вы хотите запускать внешние сценарии из Java:

Commons Exec homepage

Commons Exec API

Смежные вопросы