从 java 程序运行 bash 脚本时的奇怪行为
我有一个脚本(准确地说是 KSH 脚本),它使用 curl
命令从 FTP 服务器下载 3 个文件。
当我手动运行脚本时,即通过执行命令 ./ftp_download.sh XXX
(XXX 是脚本的参数),下载正确完成。
因为我想从 Java 程序运行脚本,所以我创建了一个简短的 Java 类,其中包含以下内容:
public class Run {
private static final String CMD = "/.../sh/ftp_download.sh XXX";
public static void main(String[] args) {
System.out.println("========================================================");
BufferedReader out = null;
try {
long startTime = System.currentTimeMillis();
String strOutputline;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
Process processus = Runtime.getRuntime().exec(CMD);
out = new BufferedReader(new InputStreamReader(processus.getInputStream()));
while ((strOutputline = out.readLine()) != null) {
now.setTime(System.currentTimeMillis());
System.out.println(sdf.format(now) + " " + strOutputline);
}
System.out.println("RESULT : " + processus.waitFor());
out.close();
processus.destroy();
long duration = System.currentTimeMillis() - startTime;
System.out.println("Duration : " + duration);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("========================================================");
System.out.println("END");
}
}
但是,当我运行这个简单的程序时,它会在 3 分 20 秒后冻结(这个持续时间始终相同,即使我多次运行 Java 程序)。 我所说的冻结是指 Java 程序仍在运行(curl
进程也是如此),但下载的文件不再增长(即 curl
不再继续下载任何数据) )...
因此,我从未在控制台中打印 RESULT: xxx
行...
什么可以解释这种奇怪的行为?
ps:在不久的将来,我将更改我的项目以便使用 Apache commons-net 库下载这些文件,但我真的想了解这种奇怪的行为!
感谢derobert,我终于成功解决了这个问题。一些解释:在正常模式下,curl
显示进度信息(包含下载数据量、剩余时间等的表格)。一段时间后,缓冲区似乎已完全填满,这就是进程冻结的原因......
I have a script (KSH script to be precise) that downloads 3 files from a FTP server, using the curl
command.
When I run manually my script, i.e. by executing the command ./ftp_download.sh XXX
(XXX are the parameters for the script), the download finishes correctly.
As I want to run the script from a Java program, I have made a short Java class that contains exactly that:
public class Run {
private static final String CMD = "/.../sh/ftp_download.sh XXX";
public static void main(String[] args) {
System.out.println("========================================================");
BufferedReader out = null;
try {
long startTime = System.currentTimeMillis();
String strOutputline;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
Process processus = Runtime.getRuntime().exec(CMD);
out = new BufferedReader(new InputStreamReader(processus.getInputStream()));
while ((strOutputline = out.readLine()) != null) {
now.setTime(System.currentTimeMillis());
System.out.println(sdf.format(now) + " " + strOutputline);
}
System.out.println("RESULT : " + processus.waitFor());
out.close();
processus.destroy();
long duration = System.currentTimeMillis() - startTime;
System.out.println("Duration : " + duration);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("========================================================");
System.out.println("END");
}
}
However, when I run this simple program, it simply freezes after exactly 3m20 (this duration is always the same, even if I run the Java program several times).
By freezing, I mean that the Java program is still running (the curl
process too) but the downloaded file is not growing anymore (i.e. curl
does not continue to download any data)...
Thus, I never get the RESULT: xxx
line printed in the console...
What can explain this strange behavior?
ps: In the near future, I will change my project in order to download these files using the Apache commons-net library, but I really want to understand this strange behavior!
Thanks to derobert, I finally manage to solve this issue. Some explanations: in normal mode, curl
is displaying a progress information (a table with the amount of data downloaded, the remaining time, etc.). After some time, the buffer seems to be completly filled, and that's why the process freezes...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不是 Java 人,而是 Unix 人,有一件事情似乎很明显:stdout 或 stderr 上的缓冲区已满,然后curl 阻塞。
如果您在静默模式下运行curl(如
curl --silent
),它会起作用吗?检查Java文档,看起来您还想使用
getErrorStream
。I'm not a Java person, but rather a Unix one, and one thing seems obvious: The buffer on either stdout or stderr is filling up, and then curl is blocking.
Does it work if you run curl in silent mode, as in
curl --silent
?Checking the Java documentation, it looks like you want to also use
getErrorStream
in addition to getInputStream.来自 进程:
因此,您需要获取 标准输出和错误输出进程并读取它们直到它们为空(即在 read())。
From Process:
So you need to get the standard output and the error output of the process and read them until they’re empty (i.e. returning
-1
on read()).