簡體   English   中英

從Java程序運行bash腳本時的奇怪行為

[英]Strange behavior when running a bash script from java program

我有一個腳本(准確地說是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");
    }

}

但是,當我運行這個簡單的程序時,它只會在3m20之后凍結(即使我多次運行Java程序,此持續時間也總是一樣)。 凍結是指Java程序仍在運行( curl進程也是如此),但下載的文件不再增長(即curl不會繼續下載任何數據)...

因此,我永遠不會在控制台上打印RESULT: xxx行。

有什么可以解釋這種奇怪的行為?

ps:在不久的將來,我將更改項目,以便使用Apache commons-net庫下載這些文件,但是我真的很想了解這種奇怪的行為!


多虧了derobert ,我終於設法解決了這個問題。 一些解釋:在正常模式下, curl顯示進度信息(包含下載數據量,剩余時間等的表)。 一段時間后,緩沖區似乎已完全填滿,這就是進程凍結的原因...

我不是Java的人,而是Unix的人,這似乎很明顯:stdout或stderr上的緩沖區已裝滿,然后curl被阻塞。

如果您以無聲模式(例如curl --silent運行curl,是否可以正常工作?

檢查Java文檔,您似乎除了getInputStream之外還希望使用getErrorStream

過程

父流程使用這些流將輸入饋入子流程並從子流程獲取輸出。 由於某些本機平台僅為標准輸入和輸出流提供了有限的緩沖區大小,因此無法及時寫入子流程的輸入流或讀取子流程的輸出流可能導致子流程阻塞,甚至死鎖。

因此,您需要獲取過程的標准輸出錯誤輸出 ,並讀取它們直到它們為空(即在read()上返回-1 )。

暫無
暫無

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

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