2014-01-17 57 views
11

在Node.js中,我使用child_process模塊​​的exec命令來調用Java中的一個算法,該算法返回大量文本以標準輸出,然後我解析並使用它。我能夠主要捕獲它,但是當它超過一定數量的行時,內容被截斷。Node.js child_process exec的標準輸出被截短

exec("sh target/bin/solver "+fields.dimx+" "+fields.dimy, function(error, stdout, stderr){ 
    //do stuff with stdout 
} 

我用一個定時器和回調試過,但都沒有成功,但我不覺得這是發生,因爲我在我的代碼引用標準輸出,才能完全恢復。我已經測試過,stdout實際上是數據丟失首先發生的地方。這不是一個異步的問題。我也在我的本地機器和Heroku上測試過,並且發生完全相同的問題,每次都在同一行號碼處截斷。

任何想法或建議可能有助於此?

回答

4

編輯: 我與dir /s我的電腦(windows)上嘗試,得到了相同的問題(它看起來像一個bug),該代碼解決這個問題對我來說:

var exec = require('child_process').exec; 

function my_exec(command, callback) { 
    var proc = exec(command); 

    var list = []; 
    proc.stdout.setEncoding('utf8'); 

    proc.stdout.on('data', function (chunk) { 
     list.push(chunk); 
    }); 

    proc.stdout.on('end', function() { 
     callback(list.join()); 
    }); 
} 

my_exec('dir /s', function (stdout) { 
    console.log(stdout); 
}) 
+0

爲什麼你認爲它看起來像一個錯誤?請看看我的回答 – olamotte

+0

@olamotte你可以看到這個答案的歷史,我增加了緩衝區大小,但它不適合我。 – damphat

+0

我也在窗戶上,它工作正常:/ – olamotte

8

我有高管。 stdout.on('end')回調被@damphat解決方案永久掛起。

另一種解決方案是增加緩衝區大小在EXEC的選項:請參閱文檔here

{ encoding: 'utf8', 
    timeout: 0, 
    maxBuffer: 200*1024, //increase here 
    killSignal: 'SIGTERM', 
    cwd: null, 
    env: null } 

引述:maxBuffer指定數據的允許在標準輸出或標準錯誤數額最大的 - 如果超過此值那麼子進程就會被殺死。我現在使用以下內容:這不需要處理在標準輸出中用逗號分隔的塊的分隔部分,而不是接受的解決方案。

exec('dir /b /O-D ^2014*', { 
    maxBuffer: 2000 * 1024 //quick fix 
    }, function(error, stdout, stderr) { 
     list_of_filenames = stdout.split('\r\n'); //adapt to your line ending char 
     console.log("Found %s files in the replay folder", list_of_filenames.length) 
    } 
); 
7

這個問題的真正(最好的)解決方案是使用spawn而不是exec。 如前所述in this article,產卵更適合處理大量的數據:

child_process.exec returns the whole buffer output from the child process. By default the buffer size is set at 200k. If the child process returns anything more than that, you program will crash with the error message "Error: maxBuffer exceeded". You can fix that problem by setting a bigger buffer size in the exec options. But you should not do it because exec is not meant for processes that return HUGE buffers to Node. You should use spawn for that. So what do you use exec for? Use it to run programs that return result statuses, instead of data.

產卵需要不同的語法比前高管:

var proc = spawn('sh', ['target/bin/solver', 'fields.dimx', 'fields.dimy']); 

proc.on("exit", function(exitCode) { 
    console.log('process exited with code ' + exitCode); 
}); 

proc.stdout.on("data", function(chunk) { 
    console.log('received chunk ' + chunk); 
}); 

proc.stdout.on("end", function() { 
    console.log("finished collecting data chunks from stdout"); 
}); 
+1

感謝您的答案!它幫助我理解,由於1MB的輸出,我的'exec'返回了一個錯誤。不幸的是,'exec'的錯誤對象只是返回命令名而沒有詳細說明錯誤的原因:'{「cmd」:「./ read_mail.sh」}' – ishahak

相關問題