java-операция Linux-вызов команды оболочки, сценарий оболочки

Shell

1. Проблемы

В последних проектах вам нужно использоватьВызовы Java выполняются на двух разных моделях, написанных на python.И получить результаты эксперимента:

1. Модель распознавания текста, работающая на сервере

2. Модель распознавания изображений, работающая в виртуальной среде annacoda в локальной среде Ubuntu.

Поскольку обе модели выполняются в терминале, рассмотрите возможность использования кода Java для прямого вызова терминала, а затем пусть терминал выполняет указанную команду оболочки, тестовый код такой же, как в разделе 2;

Поскольку модель запуска модели находится под разными путями проекта, в этом случае требуется несколько инструкций, что немного громоздко, поэтому я написал сценарий и рассмотрю возможность использования java для прямого вызова сценария оболочки;

2.java вызывает команды оболочки

1. В реальном проекте, если инструкция относительно проста, вы можете напрямую передать инструкцию для выполнения параметрам в Runtime.getRuntime().exec(). Позже Baidu обнаружил, что функция exec() имеет следующие параметры:

cmdarray: массив, содержащий вызванную команду и ее аргументы.

команда: указанная системная команда.

envp: массив строк, где переменная окружения каждого элемента задается в формате имя=значение; этот параметр имеет значение null, если дочерний процесс должен наследовать окружение текущего процесса.

dir: рабочий каталог дочернего процесса; этот параметр имеет значение null, если дочерний процесс должен наследовать рабочий каталог текущего процесса.

Process exec(String command)   
在单独的进程中执行指定的字符串命令。   
 
Process exec(String[] cmdarray)   
在单独的进程中执行指定命令和变量。   
 
--不指定环境即默认环境
 
Process exec(String[] cmdarray, String[] envp)   
在指定环境的独立进程中执行指定命令和变量。   
 
Process exec(String[] cmdarray, String[] envp, File dir)   
在指定环境和工作目录的独立进程中执行指定的命令和变量。   
 
Process exec(String command, String[] envp)   
在指定环境的单独进程中执行指定的字符串命令。   
 
Process exec(String command, String[] envp, File dir)   
在有指定环境和工作目录的独立进程中执行指定的字符串命令。

Добавьте зависимости:


        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.50</version>
        </dependency>

Код: ls;pwd

public void runPicmodels() {
      try {
           String shpath = "/home/hzhao/project_bj";
          String[] params = new String[] { "/bin/sh", "-c", "ls;pwd"};
          Process ps=Runtime.getRuntime().exec(params);
          ps.waitFor();

          BufferedReader bufrIn = new BufferedReader(new InputStreamReader(ps.getInputStream(), "UTF-8"));
          BufferedReader bufrError = new BufferedReader(new InputStreamReader(ps.getErrorStream(), "UTF-8"));

           // 读取输出 result是shell中的输出
          StringBuilder result = new StringBuilder();
          String line = null;
          while ((line = bufrIn.readLine()) != null || (line = bufrError.readLine()) != null) {
              result.append(line).append('\n');
          }

          System.out.println(result);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

Следует отметить, что функция waitFor() должна выполняться при вызове, потому что процесс оболочки является дочерним процессом процесса JAVA, а JAVA, как родительский процесс, должен дождаться завершения выполнения дочернего процесса.

3.java вызывает скрипт оболочки

1. Напишите сценарий оболочки --- тестовый сценарий

#!/usr/bin/sh
python /home/hzhao/sys.py
source activate zh_py35
cd /home/hzhao/project_bj/detection_pub
pwd
python /home/hzhao/sys.py
echo ------running-------
python __main__.pyc
echo ------success-------

2. Вызов сценария оболочки: функция exec, файл оболочки программирования параметров, параметры могут быть добавлены;


import java.io.BufferedReader; 
import java.io.InputStreamReader; 
  
public class RunShell { 
  public static void main(String[] args){ 
    try { 
      String shpath="/home/hzhao/Project/note.sh"; 
      Process ps = Runtime.getRuntime().exec(shpath); 
      ps.waitFor(); 
  
      BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream())); 
      StringBuffer sb = new StringBuffer(); 
      String line; 
      while ((line = brreadLine()) != null) { 
        sb.append(line).append("\n"); 
      } 
      String result = sbtoString(); 
      System.out.println(result); 
      }  
    catch (Exception e) { 
      e.printStackTrace(); 
      } 
  } 
} 


4. Резюме

1.ProcessBuilder
2.Runtime

3. Чтение буфера: Поскольку сценарий оболочки иногда имеет эхо-вывод или печать, буфер используется, чтобы избежать этой ситуации, данные из буфера должны быть считаны. В то же время вы можете распечатать конкретное рабочее состояние оболочки.

BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream())); 
      StringBuffer sb = new StringBuffer(); 
      String line; 
      while ((line = brreadLine()) != null) { 
        sb.append(line).append("\n"); 
      } 
      String result = sbtoString(); 
      System.out.println(result); 

4. Поскольку одна из моделей может работать только в локальной виртуальной среде annacoda, и при вызове Java среда не может быть активирована через активацию источника. Позже я подумал, что проблема в том, что не был настроен путь к переменной среды.Я пытался добавить переменные среды в envp, но не удалось; После поиска в сети я обнаружил, что когда java вызывает оболочку, она по умолчанию использует команду под системой /bin/. Особенно, если вы работаете с root-правами. На данный момент вам нужно добавить мягкую цепочку в /bin. Для моего примера выше необходимо добавить мягкую цепочку в /bin. -- Этот не пробовал. Служба инкапсуляции будет решена позже.