Saya masih mencoba untuk memahami poin-poin penting tentang bagaimana saya dapat menjalankan perintah shell linux atau windows dan menangkap keluaran dalam node.js; akhirnya, saya ingin melakukan sesuatu seperti ini ...
//pseudocode
output = run_command(cmd, args)
Bagian penting adalah yang output
harus tersedia untuk variabel (atau objek) dengan cakupan global. Saya mencoba fungsi berikut, tetapi untuk beberapa alasan, saya undefined
dicetak ke konsol ...
function run_cmd(cmd, args, cb) {
var spawn = require('child_process').spawn
var child = spawn(cmd, args);
var me = this;
child.stdout.on('data', function(me, data) {
cb(me, data);
});
}
foo = new run_cmd('dir', ['/B'], function (me, data){me.stdout=data;});
console.log(foo.stdout); // yields "undefined" <------
Saya mengalami kesulitan memahami di mana kode rusak di atas ... prototipe yang sangat sederhana dari model itu berfungsi ...
function try_this(cmd, cb) {
var me = this;
cb(me, cmd)
}
bar = new try_this('guacamole', function (me, cmd){me.output=cmd;})
console.log(bar.output); // yields "guacamole" <----
Dapatkah seseorang membantu saya memahami mengapa try_this()
berhasil, dan run_cmd()
tidak? FWIW, saya perlu menggunakan child_process.spawn
, karena child_process.exec
memiliki batas buffer 200KB.
Resolusi Akhir
Saya menerima jawaban James White, tetapi ini adalah kode persis yang berhasil untuk saya ...
function cmd_exec(cmd, args, cb_stdout, cb_end) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args),
me = this;
me.exit = 0; // Send a cb to set 1 when cmd exits
me.stdout = "";
child.stdout.on('data', function (data) { cb_stdout(me, data) });
child.stdout.on('end', function () { cb_end(me) });
}
foo = new cmd_exec('netstat', ['-rn'],
function (me, data) {me.stdout += data.toString();},
function (me) {me.exit = 1;}
);
function log_console() {
console.log(foo.stdout);
}
setTimeout(
// wait 0.25 seconds and print the output
log_console,
250);
sumber
me.stdout = "";
dalamcmd_exec()
untuk mencegah concatenatingundefined
ke awal hasilnya.Jawaban:
Ada tiga masalah di sini yang perlu diperbaiki:
Pertama , Anda mengharapkan perilaku sinkron saat menggunakan stdout secara asinkron. Semua panggilan dalam
run_cmd
fungsi Anda tidak sinkron, sehingga akan memunculkan proses turunan dan segera kembali terlepas dari apakah beberapa, semua, atau tidak ada data yang telah dibaca dari stdout. Dengan demikian, saat Anda berlariAnda mendapatkan apa pun yang terjadi untuk disimpan di foo.stdout saat ini, dan tidak ada jaminan apa yang akan terjadi karena proses anak Anda mungkin masih berjalan.
Kedua adalah bahwa stdout adalah aliran yang dapat dibaca , jadi 1) peristiwa data dapat dipanggil beberapa kali, dan 2) panggilan balik diberikan buffer, bukan string. Mudah untuk diperbaiki; ganti saja
ke
sehingga kami mengubah buffer kami menjadi string dan menambahkan string itu ke variabel stdout kami.
Ketiga , Anda hanya dapat mengetahui bahwa Anda telah menerima semua keluaran saat mendapatkan peristiwa 'end', yang berarti kita memerlukan listener dan callback lain:
Jadi, hasil akhir Anda adalah ini:
sumber
this.stdout = "";
di dalamrun()
fungsi, jika tidak, Andaconsole.log(foo.sdtout);
akan diawali denganundefined
.Versi sederhana dari jawaban yang diterima (poin ketiga), berhasil untuk saya.
Pemakaian:
sumber
child.stdout.on('close', (errCode) => { console.log(errCode) } )
Saya menggunakan ini lebih singkat:
itu bekerja dengan sempurna. :)
sumber
sys.puts()
tidak digunakan lagi pada tahun 2011 (dengan Node.js v0.2.3). Anda harus menggunakanconsole.log()
sebagai gantinya.Cara termudah adalah dengan hanya menggunakan ShellJS lib ...
EXEC Contoh:
ShellJs.org mendukung banyak perintah shell umum yang dipetakan sebagai fungsi NodeJS termasuk:
sumber
shell.exec("foo.sh arg1 arg2 ... ")
.foo.sh
Skrip Anda dapat mereferensikan ini menggunakan$1
,$2
... dll.Saya memiliki masalah yang sama dan saya akhirnya menulis ekstensi node untuk ini. Anda dapat melihat repositori git. Ini open source dan gratis dan semua hal bagus itu!
https://github.com/aponxi/npm-execxi
Petunjuk penggunaan ada di file ReadMe . Jangan ragu untuk membuat permintaan penarikan atau mengirimkan masalah!
Saya pikir itu layak untuk disebutkan.
sumber
@ TonyO'Hagan adalah
shelljs
jawaban yang komprehensif , tetapi, saya ingin menyoroti versi sinkron dari jawabannya:sumber
Satu baris sinkron:
require('child_process').execSync("echo 'hi'", function puts(error, stdout, stderr) { console.log(stdout) });
sumber
Ada konflik variabel dalam
run_cmd
fungsi Anda :Cukup ubah menjadi ini:
Untuk melihat kesalahan selalu tambahkan ini:
EDIT Kode Anda gagal karena Anda mencoba menjalankan
dir
yang tidak disediakan sebagai program mandiri terpisah. Ini adalah perintah dalamcmd
proses. Jika Anda ingin bermain dengan filesystem gunakan nativerequire( 'fs' )
.Atau (yang tidak saya rekomendasikan) Anda dapat membuat file batch yang kemudian dapat Anda jalankan. Perhatikan bahwa OS secara default mengaktifkan file batch melalui
cmd
.sumber
C:\Windows\System32\netstat.exe
, ini masih tidak membuahkan hasil ... sintaks yang tepat saya adalahfoo = new run_cmd('netstat.exe', ['-an'], function (me, data){me.stdout=data;});
... Saya juga mencoba jalur lengkap tanpa hasil sejauh iniAnda sebenarnya tidak mengembalikan apa pun dari fungsi run_cmd Anda.
Bekerja dengan baik. :)
sumber
return
diperlukan selama Anda mengatur atribut objek dengan benarVersi yang dijanjikan dari jawaban paling banyak diberikan:
Menggunakan:
sumber