Problem 1.

In a recent project, I needed to run two different models written in Python using Java calls and get experimental results:

1. Text recognition model running on the server

2. Image recognition model running in annacoda virtual environment in local Ubuntu

Since both models execute at the terminal, consider using Java code to directly call the terminal and then have the terminal execute the specified shell command. Test the code as shown in Section 2.

Since the startup model of the model is in different project paths, several instructions are required in this case, which is a little tedious, so I wrote a script, considering using Java to directly call shell script;

2. Java invokes shell commands

1. In actual projects, if the instructions are simple, the instructions to be executed can be directly passed to the parameters in Runtime.geTruntime ().exec(). Later, Baidu found that exec() has the following parameters:

Cmdarray: An array containing the command called and its arguments.

Command: a specified system command.

Envp: array of strings where each element’s environment variable is set to the format name=value; Null if the child process should inherit the environment of the current process.

Dir: the working directory of the child process. Null if the child process should inherit the working directory of the current process.

Process exec(String command) executes the specified string command in a separate process. Processexec(String[] cmdarray) Executes specified commands and variables in a separate process. -- Default environment Process is not specifiedexec(String[] cmDARray, String[] envp) Executes specified commands and variables in a separate process in the specified environment. Processexec(String[] cmdarray, String[] envp, File dir) Executes the specified commands and variables in a separate process in the specified environment and working directory. Processexec(String command, String[] envp) executes the specified String command in a separate process in the specified environment. Processexec(String command, String[] envp, File dir) executes the specified String command in a separate process with the specified environment and working directory.Copy the code

Add dependency packages:

<dependency> <groupId>com.jcraft</groupId> <artifactId> JSCH </artifactId> <version>0.1.50</version> </dependency>Copy the code

Code: ls; pwd

public void runPicmodels(a) {
      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 is the output in the 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(); }}Copy the code

Note that waitFor() is invoked because the shell process is the child of the JAVA process, and JAVA as the parent waits for the child to finish executing.

3. Java invokes shell scripts

1. Write shell scripts — test scripts

#! /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-------

Copy the code

2. Call shell script: exec function, parameter programming shell file, can add parameters;


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(); }}}Copy the code

4. To summarize

1.ProcessBuilder

2.Runtime

3. Read buffer: Shell scripts sometimes echo output or print, resulting in the buffer used up, to avoid this situation, you need to read buffer data. You can also print the shell running status.

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); 
Copy the code

4. Because one of the models can only run in the local Annacoda virtual environment, which is always not activated by source Activate when Java calls are made. It was thought that the environment variable path was not configured, and the attempt to add environment variables to ENVP failed. After searching the network, I found that Java used the system /bin/ instruction by default when calling shell. Especially if you are running with root privileges. At this point, you need to add soft chain under /bin. For my example above, add a soft chain under /bin. — This has not been tried. Then encapsulate the service solution.