Gunakan child_process.execSync tetapi tetap output di konsol


160

Saya ingin menggunakan execSyncmetode yang ditambahkan di NodeJS 0.12 tetapi masih memiliki output di jendela konsol dari mana saya menjalankan skrip Node.

Misalnya jika saya menjalankan skrip NodeJS yang memiliki baris berikut saya ingin melihat hasil lengkap dari perintah rsync "live" di dalam konsol:

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

Saya mengerti bahwa execSyncmengembalikan ouput dari perintah dan bahwa saya dapat mencetaknya ke konsol setelah eksekusi tetapi dengan cara ini saya tidak memiliki output "hidup" ...

Jawaban:


324

Anda dapat meneruskan stdio orang tua ke proses anak jika itu yang Anda inginkan:

require('child_process').execSync(
    'rsync -avAXz --info=progress2 "/src" "/dest"',
    {stdio: 'inherit'}
);

3
Ini berarti bahwa proses anak akan menggunakan aliran stdin, stdout, dan stderr orang tua. Jadi ketika proses anak menulis kepada salah satu dari mereka, itu sebenarnya akan ditulis langsung ke aliran orang tua.
gregers

7
Ini adalah jawaban yang sangat berharga, karena dokumentasi resmi tidak benar-benar eksplisit tentang sintaks yang diharapkan.
chikamichi

49
Alih-alih [0,1,2]saya telah menggunakan 'inherit', yang setara dengan [process.stdin, process.stdout, process.stderr]atau [0,1,2]sesuai dokumen
Kurt


2
@Booligoosh Daripada hanya menambahkan {stdio:'inherit'}, Anda harus menambahkan .toString () dan kemudian memanggil console.log secara manual dengan hasilnya. Selain itu, bahkan tidak memenuhi persyaratan pertanyaan untuk melihat output perintah "hidup". Saya tidak berpikir itu "jauh lebih sederhana", pada kenyataannya saya tidak berpikir itu lebih sederhana sama sekali.
boileau

19

Anda cukup menggunakan .toString().

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

Ini telah diuji pada Node v8.5.0, saya tidak yakin tentang versi sebelumnya. Menurut @etov , itu tidak berfungsi v6.3.1- Saya tidak yakin tentang di antaranya.


3
Ini tidak berfungsi pada kegagalan (kode status! = 0) karena .execSync()melempar Errorinstance.
Álvaro González

Tidak berfungsi untuk saya, yaitu output hanya ditulis setelah perintah selesai. Apakah ini berlaku untuk versi tertentu? simpul saya -v: v6.3.1
etov

Silakan pertimbangkan untuk memperbarui jawaban untuk dicatat bahwa itu hanya berlaku untuk versi node tertentu - ini akan membuatnya lebih bermanfaat bagi orang lain
etov

1
Turunkan sejak sekarang dengan cara yang berkaitan dengan pertanyaan tentang output selama perintah dieksekusi.
karfau

14

Kecuali Anda mengarahkan ulang stdout dan stderr seperti jawaban yang diterima menyarankan, ini tidak mungkin dengan execSync atau spawnSync. Tanpa mengarahkan stdout dan stderr, perintah-perintah itu hanya mengembalikan stdout dan stderr ketika perintah selesai.

Untuk melakukan ini tanpa mengarahkan ulang stdout dan stderr, Anda harus menggunakan spawn untuk melakukan ini, tetapi ini cukup mudah:

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);
});

Saya menggunakan perintah ls yang secara rekursif mendaftar file sehingga Anda dapat mengujinya dengan cepat. Spawn mengambil sebagai argumen pertama nama yang dapat dieksekusi yang Anda coba jalankan dan karena argumen kedua dibutuhkan array string yang mewakili setiap parameter yang ingin Anda sampaikan ke executable itu.

Namun, jika Anda menggunakan execSync dan tidak dapat mengalihkan stdout atau stderr karena suatu alasan, Anda dapat membuka terminal lain seperti xterm dan memberikannya perintah seperti ini:

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

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

Ini akan memungkinkan Anda untuk melihat apa perintah Anda lakukan di terminal baru tetapi masih memiliki panggilan sinkron.


2
Contoh menggunakan spawn mungkin benar, tetapi pernyataan pembuka tentang tidak akan menggunakan execSync tidak akurat. Lihat jawaban dari @regreg
AgDude
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.