2013-01-15 38 views
45

Tôi có một tập lệnh xuất 'hi', ngủ trong một giây, đầu ra 'hi', ngủ trong 1 giây, v.v. Bây giờ tôi nghĩ rằng tôi sẽ có thể giải quyết vấn đề này với mô hình này.Node.js sinh ra quá trình con và nhận đầu ra của thiết bị đầu cuối trực tiếp

var spawn = require('child_process').spawn, 
temp = spawn('PATH TO SCRIPT WITH THE ABOVE BEHAVIOUR'); 

temp.stdout.pipe(process.stdout); 

Bây giờ vấn đề là nhiệm vụ cần được hoàn thành để hiển thị đầu ra. Khi tôi hiểu nó, điều này là do thực tế là quá trình mới sinh ra có quyền kiểm soát thực hiện. Rõ ràng node.js không hỗ trợ chủ đề để giải pháp nào? Ý tưởng của tôi là để có thể chạy hai trường hợp, đầu tiên cho mục đích cụ thể của việc tạo ra các nhiệm vụ và có nó ống đầu ra để xử lý của trường hợp thứ hai, xem xét điều này có thể đạt được.

Trả lời

52

Tôi vẫn bị ướt chân với Node.js, nhưng tôi có một vài ý tưởng. đầu tiên, tôi tin rằng bạn cần sử dụng execFile thay vì spawn; execFile là khi bạn có đường dẫn đến tập lệnh, trong khi spawn là để thực thi lệnh nổi tiếng mà Node.js có thể giải quyết theo đường dẫn hệ thống của bạn.

1. Provide a callback để xử lý đầu ra đệm:

var child = require('child_process').execFile('path/to/script', [ 
    'arg1', 'arg2', 'arg3', 
], function(err, stdout, stderr) { 
    // Node.js will invoke this callback when the 
    console.log(stdout); 
}); 

2. Thêm một người biết lắng nghe để quá trình con stdout stream (9thport.net)

var child = require('child_process').execFile('path/to/script', [ 
    'arg1', 'arg2', 'arg3' ]); 
// use event hooks to provide a callback to execute when data are available: 
child.stdout.on('data', function(data) { 
    console.log(data.toString()); 
}); 

Hơn nữa, có vẻ như là lựa chọn đó bạn có thể tách quá trình sinh ra khỏi thiết bị đầu cuối điều khiển của Node, điều này sẽ cho phép nó chạy không đồng bộ. Tôi đã không kiểm tra này được nêu ra, nhưng có những ví dụ trong API docs rằng đi một cái gì đó như thế này:

child = require('child_process').execFile('path/to/script', [ 
    'arg1', 'arg2', 'arg3', 
], { 
    // detachment and ignored stdin are the key here: 
    detached: true, 
    stdio: [ 'ignore', 1, 2 ] 
}); 
// and unref() somehow disentangles the child's event loop from the parent's: 
child.unref(); 
child.stdout.on('data', function(data) { 
    console.log(data.toString()); 
}); 
+5

Tiền thưởng điểm nếu bạn có thể giải thích làm thế nào để làm điều này với exec() như tôi cần phải thực hiện một cmd shell. – DynamicDan

+1

Bạn có thể sử dụng 'child.spawn()' với tùy chọn 'shell' được đặt thành' true'. https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options – CedX

+1

Bạn cũng có thể đặt con.stdout trực tiếp vào process.stdout bằng 'child.stdout.pipe (process.stdout); ' – darkadept

1

con:

setInterval(function() { 
    process.stdout.write("hi"); 
}, 1000); // or however else you want to run a timer 

mẹ:

require('child_process').fork('./childfile.js'); 
// fork'd children use the parent's stdio 
60

Đó là dễ dàng hơn nhiều hiện nay (2 năm sau)!

Spawn trả về childObject, sau đó bạn có thể nghe sự kiện bằng.Các sự kiện bao gồm:

  • Class: ChildProcess
    • sự kiện: 'lỗi'
    • sự kiện: 'thoát'
    • sự kiện: 'gần'
    • tổ chức sự kiện: 'ngắt kết nối'
    • Sự kiện: 'message'

Ngoài ra còn có một loạt các đối tượng từ childObject, đó là:

  • Class: ChildProcess
    • child.stdin
    • child.stdout
    • child.stderr
    • con .stdio
    • child.pid
    • child.connected
    • child.kill ([tín hiệu])
    • child.send (message [, sendHandle] [, callback])
    • child.disconnect()

Xem biết thêm thông tin ở đây về childObject: https://nodejs.org/api/child_process.html

Vì vậy, kết hợp tất cả những điều này, bạn nhận được:

var spawn = require('child_process').spawn; 
var child = spawn('node ./commands/server.js'); 
child.stdout.on('data', function(data) { 
    console.log('stdout: ' + data); 
    //Here is where the output goes 
}); 
child.stderr.on('data', function(data) { 
    console.log('stderr: ' + data); 
    //Here is where the error output goes 
}); 
child.on('close', function(code) { 
    console.log('closing code: ' + code); 
    //Here you can get the exit code of the script 
}); 

Và đó là cách bạn có thể nhận được đầu ra bằng nút!

+4

+1, điều này sẽ là được chọn là câu trả lời đúng ngay bây giờ. Chỉ cần một lưu ý, biến dữ liệu trong gọi lại đến trong như là đối tượng đệm. Bạn có thể sử dụng '' 'child.stdout.setEncoding ('utf8')' '' nếu bạn muốn các chuỗi utf8 đến. – Ashish

+0

Tôi đang cố gắng chạy một kịch bản lệnh python; hoạt động của nó nhưng đầu ra không đến đây. 'var spawn = require ('child_process'). spawn; var child = spawn ('python', ['/my/path/to/python/file/my_python_file.py']); child.stdout.on ('data', function (data) { console.log ('stdout:' + data); }); child.stderr.on ('data', function (data) { console.log ('stderr:' + data); }); child.on ('close', function (code) { console.log ('mã đóng:' + mã); }); ' – ishandutta2007

10

Tôi gặp một chút rắc rối khi nhận kết quả ghi nhật ký từ lệnh "npm install" khi tôi sinh ra npm trong một tiến trình con. Ghi nhật ký phụ thuộc thời gian thực không hiển thị trong bảng điều khiển chính.

Cách đơn giản nhất để làm những gì các poster ban đầu muốn có vẻ là này (spawn NPM trên cửa sổ và đăng nhập tất cả mọi thứ để điều khiển cha mẹ):

var args = ['install']; 

var options = { 
    stdio: 'inherit' //feed all child process logging into parent process 
}; 

var childProcess = spawn('npm.cmd', args, options); 
childProcess.on('close', function(code) { 
    process.stdout.write('"npm install" finished with code ' + code + '\n'); 
}); 
0

tôi thấy mình cần chức năng này thường đủ mà tôi đóng gói nó vào thư viện có tên là std-pour. Nó sẽ cho phép bạn thực hiện một lệnh và xem đầu ra theo thời gian thực. Để cài đặt đơn giản:

npm install std-pour 

Sau đó nó đủ đơn giản để thực hiện một lệnh và xem kết quả trong thời gian thực:

const { pour } = require('std-pour'); 
pour('ping', ['8.8.8.8', '-c', '4']).then(code => console.log(`Error Code: ${code}`)); 

Nó hứa dựa để bạn có thể chuỗi nhiều lệnh. Nó thậm chí có chức năng chữ ký tương thích với child_process.spawn do đó, nó phải là một thả thay thế bất cứ nơi nào bạn đang sử dụng nó.

3

Dưới đây là cách tiếp cận sạch nhất tôi đã tìm thấy:

require("child_process").spawn('bash', ['./script.sh'], { 
    cwd: process.cwd(), 
    detached: true, 
    stdio: "inherit" 
}); 
Các vấn đề liên quan