невозможно запустить скрипт ksh из java: java.io.IOException:.: не найдено - PullRequest
1 голос
/ 09 февраля 2009

Я пытался запустить скрипт оболочки из кода Java, но столкнулся с проблемой. Скрипт находится в файле batchstart.sh -

#!/bin/ksh
export DISPLAY=:0.0

Теперь скрипт запускается с точкой в ​​командной строке -. batchstart.sh

Как мне запустить его из Java? Мой код Java ниже. Выдает следующее исключение -

java.io.IOException: .: not found
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:102)
    at java.lang.ProcessImpl.start(ProcessImpl.java:65)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:451)
    at java.lang.Runtime.exec(Runtime.java:591)
    at java.lang.Runtime.exec(Runtime.java:429)
    at SetDisplay.main(SetDisplay.java:12)
import java.io.*;

public class SetDisplay {

   public static void main(String[] args) {

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

       try {
           proc = Runtime.getRuntime().exec(". batchstart.sh", null, wd);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Как мне запустить скрипт оболочки?

Я также попробовал следующий код, но он тоже не работает.

File wd = new File("/bin"); 
System.out.println(wd); 
Process proc = null; 
try { 
  proc = Runtime.getRuntime().exec("/bin/bash", null, wd); 
} 
catch (IOException e) { 
  e.printStackTrace(); 
} 
if (proc != null) { 
  BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
  PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true); 
  out.println("cd /home/"); 
  out.println(". batchstart.sh"); 
  out.println("exit"); 
  try { 
    String line; 
    while ((line = in.readLine()) != null) { 
      System.out.println(line); 
    } 
    proc.waitFor(); 
    in.close(); 
    out.close(); 
    proc.destroy(); 
  } 
  catch (Exception e) { 
    e.printStackTrace(); 
  } 
}

Ответы [ 3 ]

1 голос
/ 09 февраля 2009

Исходная команда (".") является встроенной в оболочку. Вы должны явно запустить /bin/ksh, передав имя скрипта в качестве аргумента (за которым следуют любые аргументы скрипта).

У вас есть большая проблема, если вам нужно для создания сценария. Обычно это означает, что изменения среды происходят в контексте текущей оболочки, а не подоболочки.

Это не будет работать с Java, так как Java не является оболочкой. Вам нужно выяснить, как изменить среду с помощью Java.

Конечно, если я ошибаюсь и в этом сценарии есть нечто большее, чем просто установка DISPLAY, он может работать как предложено.

Метод, который вам нужно будет использовать, зависит от того, чего вы пытаетесь достичь (например, «Запускаете ли вы другие программы, использующие exec (), которые полагаются на установку DISPLAY?» Или «Нужна ли ваша Java-программа?»). DISPLAY будет установлен? ").

Если, как вы утверждаете в своем комментарии, только ваша Java-программа нуждается в установке DISPLAY, просто установите ее снаружи перед запуском вашей программы. Создайте cmd (или bash) файл, который устанавливает переменную DISPLAY , затем вызывает JRE для запуска вашей программы.

#/bin/ksh
export DISPLAY-:0.0
/usr/bin/jre/java your_program blah.blah.blah

Я бы также изменил ваш main(), чтобы проверить, что он установлен на что-то, и корректно завершил работу, если нет:

if (System.getenv ("DISPLAY") == null)
    // doesn't exist, exit gracefully.
0 голосов
/ 09 февраля 2009

При запуске из командной строки использование точки в начале скрипта означает, что скрипт должен запускаться в среде current , вместо того, чтобы создавать новый подоболочку и использовать новый копия текущей среды. Это позволяет экспортировать новое значение переменной среды для использования командами, запускаемыми позже из той же интерактивной оболочки.

Очевидно, что эта техника работает, только если вы запускаете свой скрипт batchstart.sh из реальной оболочки. Java не знает, как работает этот механизм, и поэтому точка для него ничего не значит. Сценарий не может изменить среду Java-процесса, из которого он был вызван.

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

0 голосов
/ 09 февраля 2009

Период "." является встроенной оболочкой и выполняет скрипт «на месте», аналогично #include в C / C ++. С помощью "." вне shell-скрипта не имеет смысла.

Если вы хотите запустить скрипт из Java, вы должны выполнить интерпретатор скрипта (/ bin / ksh):

  Runtime.getRuntime().exec("/bin/ksh batchstart.sh", ...)

но учтите, что это не семантически эквивалентно, так как вы выполняете batchstart.sh как подпроцесс вместо его поиска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...