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. -- Этот не пробовал. Служба инкапсуляции будет решена позже.