【发布时间】:2021-05-09 19:22:05
【问题描述】:
我有以下问题,这似乎是由我的 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”步骤。由于我不是 Java 开发人员,而且我对语言不太熟悉,所以我觉得这与 docker pull 命令的多并发性质以及 Java Process Builder 如何执行 shell 脚本的方式有关
运行shell脚本的Java类是这样的
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();
}
注释行是我尝试的不同方式。
如果有人遇到类似问题,任何帮助将不胜感激!
【问题讨论】:
-
任何地方都有例外吗?
-
不,脚本以 0 退出 - 当我记录从“process.waitFor()”返回的代码时,意味着一切顺利。
-
shell 脚本中实际运行的命令的组合输出是什么?
-
my-app my-app my-app:latest 2b04e95049b020378b002229c91838b1f3e132af96aec1d5b7efce8ebd7111c6 当我通过 ProcessBuilder 运行它时也会发生同样的情况,但它不会从 Docker Hub 中提取最新图像,基本上它的作用是停止该应用程序,然后重新运行它,但它使用旧图像运行它,新图像从未下载过。这就是我不明白的原因与执行 Pull 命令时 docker CLI 执行的多下载有关。不知道怎么解释
-
您可以将
exec > /tmp/log.txt 2>&1作为脚本中的第二行,以将任何错误记录到文件中,而不是丢弃它们。这不是在某些 Windows 兼容层中运行的,对吧?