2015-05-08 56 views
82

我想使用在NodeJS 0.12中添加的execSync方法,但仍然在控制檯窗口中輸出我運行Node腳本的輸出。使用child_process.execSync,但保持控制檯輸出

E.g.如果我運行具有以下行腳本的NodeJS我想看到控制檯內部的rsync命令的全部輸出「活」:

require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"'); 

據我瞭解,命令和execSync返回輸出中我可以在執行後將其打印到控制檯,但通過這種方式,我沒有「活動」輸出...

回答

175

您可以通過parent´s stdio to the child process如果that's你想要什麼:

require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"', {stdio:[0,1,2]}); 
+7

此答案應被標記爲接受的答案。 – thorn

+1

stdio [0,1,2]是什麼意思? – Richard

+3

這意味着子進程將使用父進程的stdin,stdout和stderr流。所以當子進程寫入其中的任何一個時,它實際上會直接寫入父進程流。 – gregers

11

除非您按照接受的答案所示重定向stdout和stderr,否則這對execSync或spawnSync來說是不可能的。如果不重定向stdout和stderr,那麼這些命令只會在命令完成時返回stdout和stderr。

要做到這一點,而不會重定向輸出和錯誤,你將需要使用菌種要做到這一點,但它非常直截了當:

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

//kick off process of listing files 
var child = spawn('ls', ['-l', '/']); 

//spit stdout to screen 
child.stdout.on('data', function (data) { process.stdout.write(data.toString()); }); 

//spit stderr to screen 
child.stderr.on('data', function (data) { process.stdout.write(data.toString()); }); 

child.on('close', function (code) { 
    console.log("Finished with code " + code); 
}); 

我用ls命令是遞歸列出文件,這樣就可以了快速測試。 Spawn將第一個參數作爲您要運行的可執行文件的名稱,因爲它是第二個參數,它需要一個表示要傳遞給該可執行文件的每個參數的字符串數組。

但是,如果你正在使用execSync設置,不能重定向stdout或stderr出於某種原因,你可以打開xterm這樣的其他終端,併爲其傳遞命令,如下所示:

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

execSync("xterm -title RecursiveFileListing -e ls -latkR /"); 

這將讓你看到你的命令在新終端中做了什麼,但仍然有同步呼叫。

+2

使用spawn的示例可能是正確的,但關於不會使用execSync的開放語句不準確。請參閱@gregers的答案 – AgDude

7

您可以簡單地使用.toString()

var result = require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"').toString(); 
console.log(result); 

這已經在節點v8.5.0上測試,我不確定以前的版本。根據@etov,它不適用於v6.3.1 - 我不確定介於兩者之間。

+1

因爲'.execSync()'拋出一個'Error'實例,所以這在失敗(狀態碼!= 0)時不起作用。 –

+1

爲什麼不是這個答案!? :) – calcazar

+0

不適用於我,即輸出僅在命令完成後寫入。這是否適用於特定版本?我的節點-v:v6.3.1 – etov