簡體   English   中英

Shell 腳本由於 docker 拉動而過早退出,同時通過 ProcessBuilder 運行

[英]Shell script exit too early due to docker pull, while running through ProcessBuilder

我有以下問題,這似乎是由我的 shell 腳本中的“docker pull”引起的,因為 pull 同時工作

#!/bin/bash   
#VARIABLES
    NAME="my-app"
    IMAGE="my-image:latest"
#DOCKER
    docker stop $NAME
    docker rm $NAME
    docker pull -q $IMAGE
    docker run --name $NAME -d -p 1234:8080 --log-opt fluentd-address=localhost:2233 $IMAGE

通過終端運行腳本工作正常,一切都按預期工作。 但是當我使用 Java 的 ProcessBuilder 運行它時,腳本退出的速度要快得多,而且它似乎跳過了“docker pull”步驟。 As i am not a Java developer and I am not very well familiar with the Language I have the feeling that is something related to the multi-concurrent nature of the docker pull command and the way how the Java Process Builder executes the shell script

運行 shell 腳本的 Java class 是這個

try {

    Collection<Task> tasks = taskService.getProjectTasksByProjectKey(projectId);

    Task findTask = findTaskByTaskId(tasks, taskId);
    if (findTask.getTaskId() != null) {
        ProcessBuilder pb = new ProcessBuilder(findTask.getCmdPath());
        Process process = pb.start();

        String output;

        try (InputStream in = process.getInputStream();
             InputStream err = process.getErrorStream();
             OutputStream closeOnly = process.getOutputStream()) {
            while (process.isAlive()) {
                long skipped = in.skip(in.available())
                        + err.skip(err.available());
                if(skipped == 0L) {
                    process.waitFor(5L, TimeUnit.MILLISECONDS);
                }
            }
            output = loadStream(in);
        } finally {
            process.destroy();
        }

//                String error  = loadStream(process.getErrorStream());
//                int rc = process.waitFor();

//                log.debug("exit code ->>> " + rc);
//                StringBuilder output = new StringBuilder();
//                BufferedReader reader = new BufferedReader(
//                        new InputStreamReader(process.getInputStream()));
//
//                String line;
//
//                while ((line = reader.readLine()) != null) {
//                    output.append(line + "\n");
//                }
//
//                int exitVal = process.waitFor();
//                if (exitVal == 0) {
//                    System.out.println(output);
//
//                    return output.toString();
//                } else {
//                    //abnormal...
//                }

        return output;
    }
    else {
        throw new InvalidTaskModelException(taskId);
    }
} catch (InvalidModelException e) {
    throw new InvalidModelException(projectId);
} catch (IOException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}

return null;
}

private static String loadStream(InputStream s) throws Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(s));
StringBuilder sb = new StringBuilder();
String line;
while((line=br.readLine()) != null)
    sb.append(line).append("\n");
return sb.toString();
}

注釋行是我嘗試做的不同方式。

如果有人遇到類似的問題,任何幫助將不勝感激!

很高興您已經注意了進程的 STDOUT 和 STDIN。 但不要跳過將它們復制到 System.out,這樣您就可以看到發生了什么。 我懷疑有些事情沒有按照您的預期進行。

查看您發布的 bash 腳本以及您嘗試運行多個進程的事實:您的 java 代碼是否可能逐行運行 bash 腳本? 請注意您的 java 程序不是 BASH 解釋器,因此例如變量替換不應該起作用。

為什么你不能在線程中運行每個命令並將它們連接起來,除非 therad 1 沒有完成。 下一個線程無法啟動。

還請添加命令以驗證圖像是否已成功下載

docker pull -q $IMAGE
docker images | grep $IMAGE
docker run --name $NAME -d -p 1234:8080 --log-opt fluentd-address=localhost:2233 $IMAGE 

我猜這里有兩種可能性

  1. 如果可能,檢查本地目錄權限,給它 755 權限。
  2. Java 進程本身由於權限問題無法執行 docker 命令,請以 sudo 用戶身份運行進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM