Node.js가 하위 프로세스를 생성하고 터미널 출력을 라이브로 가져옵니다.
저는 '안녕'을 출력하고, '안녕'을 출력하고, '안녕'을 출력하고, 1초간 자는 등의 스크립트를 가지고 있습니다.이제 저는 이 모델로 이 문제를 해결할 수 있을 것이라고 생각했습니다.
var spawn = require('child_process').spawn,
temp = spawn('PATH TO SCRIPT WITH THE ABOVE BEHAVIOUR');
temp.stdout.pipe(process.stdout);
이제 문제는 출력이 표시되려면 작업이 완료되어야 한다는 것입니다.제가 알기로는 새로 생성된 프로세스가 실행 제어를 하기 때문입니다.분명히 node.js는 스레드를 지원하지 않는데 솔루션이 있습니까?제 아이디어는 두 개의 인스턴스를 실행하는 것이었는데, 첫 번째 인스턴스는 작업을 생성하는 특정 목적을 위해 실행하고 두 번째 인스턴스의 프로세스에 출력을 파이프로 연결하는 것이었습니다.
이제 훨씬 쉬워졌습니다. (6년 후)!
Spain은 childObject를 반환하고 이벤트를 수신할 수 있습니다.이벤트는 다음과 같습니다.
- 클래스: 하위 프로세스
- 이벤트: '오류'
- 이벤트: '종료'
- 이벤트: '닫기'
- 이벤트: '연결 끊기'
- 이벤트: '메시지'
childObject에는 다음과 같은 개체가 있습니다.
- 클래스: 하위 프로세스
- child.stdin
- child.stdout
- child.sterr
- child.stydo
- 어린애 같은
- 자식.연관의
- child.kill([해적]
- child.send(message[, sendHandle][, 콜백])
- child.disconnect ()
childObject에 대한 자세한 내용은 여기를 참조하십시오. https://nodejs.org/api/child_process.html
비동기식
노드가 계속 실행할 수 있는 상태에서 프로세스를 백그라운드에서 실행하려면 비동기 방법을 사용합니다.프로세스가 완료된 후에도 프로세스에 출력이 있을 때(예: 스크립트의 출력을 클라이언트로 보내려는 경우) 작업을 수행하도록 선택할 수 있습니다.
child_process.spawn(...; (노드 v0.1.90)
var spawn = require('child_process').spawn;
var child = spawn('node ./commands/server.js');
// You can also use a variable to save the output
// for when the script closes later
var scriptOutput = "";
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
//Here is where the output goes
console.log('stdout: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', function(data) {
//Here is where the error output goes
console.log('stderr: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.on('close', function(code) {
//Here you can get the exit code of the script
console.log('closing code: ' + code);
console.log('Full output of script: ',scriptOutput);
});
콜백 + 비동기식 방법을 사용하는 방법은 다음과 같습니다.
var child_process = require('child_process');
console.log("Node Version: ", process.version);
run_script("ls", ["-l", "/home"], function(output, exit_code) {
console.log("Process Finished.");
console.log('closing code: ' + exit_code);
console.log('Full output of script: ',output);
});
console.log ("Continuing to do node things while the process runs at the same time...");
// This function will output the lines from the script
// AS is runs, AND will return the full combined output
// as well as exit code when it's done (using the callback).
function run_script(command, args, callback) {
console.log("Starting Process.");
var child = child_process.spawn(command, args);
var scriptOutput = "";
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
console.log('stdout: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', function(data) {
console.log('stderr: ' + data);
data=data.toString();
scriptOutput+=data;
});
child.on('close', function(code) {
callback(scriptOutput,code);
});
}
위의 방법을 사용하여 스크립트의 모든 출력 라인을 클라이언트로 전송할 수 있습니다(예: Socket.io 를 사용하여 다음 날짜에 이벤트를 수신할 때 각 라인을 전송).stdout
또는stderr
).
동기식
노드가 작업을 중지하고 스크립트가 완료될 때까지 기다리려면 동기화 버전을 사용할 수 있습니다.
child_process.spawSync(...; (노드 v0.11.12+)
이 방법의 문제:
- 스크립트를 완료하는 데 시간이 오래 걸리면 서버가 해당 시간 동안 중단됩니다!
- stdout은 스크립트 실행이 완료된 후에만 반환됩니다.동기식이므로 현재 줄이 끝날 때까지 계속할 수 없습니다.따라서 산란 라인이 완료될 때까지 'stdout' 이벤트를 캡처할 수 없습니다.
사용 방법:
var child_process = require('child_process');
var child = child_process.spawnSync("ls", ["-l", "/home"], { encoding : 'utf8' });
console.log("Process finished.");
if(child.error) {
console.log("ERROR: ",child.error);
}
console.log("stdout: ",child.stdout);
console.log("stderr: ",child.stderr);
console.log("exist code: ",child.status);
아직도 Node.js에 흠뻑 젖고 있지만 몇 가지 아이디어가 있습니다.먼저, 저는 당신이 사용할 필요가 있다고 생각합니다.execFile
에 spawn
;execFile
때 하는 반면, 스립트에대있경경위것만한이지우를는한로가크,▁you▁to▁is만,▁for,spawn
시스템 경로에 대해 Node.js가 확인할 수 있는 잘 알려진 명령을 실행하기 위한 것입니다.
버퍼링된 출력을 처리할 콜백을 제공합니다.
var child = require('child_process').execFile('path/to/script', [
'arg1', 'arg2', 'arg3',
], function(err, stdout, stderr) {
// Node.js will invoke this callback when process terminates.
console.log(stdout);
});
하위 프로세스의 stdout 스트림에 수신기 추가(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());
});
또한 생성된 프로세스를 노드의 제어 터미널에서 분리하여 비동기적으로 실행할 수 있는 옵션도 있습니다.아직 테스트하지 않았지만 API 문서에는 다음과 같은 예가 있습니다.
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());
});
제가 찾은 가장 깨끗한 접근법은 다음과 같습니다.
require("child_process").spawn('bash', ['./script.sh'], {
cwd: process.cwd(),
detached: true,
stdio: "inherit"
});
하위 프로세스에서 npm을 생성할 때 "npm install" 명령에서 로깅 출력을 가져오는 데 약간의 문제가 있었습니다.종속성의 실시간 로깅이 상위 콘솔에 표시되지 않았습니다.
원래 포스터가 원하는 것을 수행하는 가장 간단한 방법은 다음과 같습니다(창에 npm을 생성하고 모든 것을 상위 콘솔에 기록).
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');
});
PHP 유사 경유
import { spawn } from 'child_process';
export default async function passthru(exe, args, options) {
return new Promise((resolve, reject) => {
const env = Object.create(process.env);
const child = spawn(exe, args, {
...options,
env: {
...env,
...options.env,
},
});
child.stdout.setEncoding('utf8');
child.stderr.setEncoding('utf8');
child.stdout.on('data', data => console.log(data));
child.stderr.on('data', data => console.log(data));
child.on('error', error => reject(error));
child.on('close', exitCode => {
console.log('Exit code:', exitCode);
resolve(exitCode);
});
});
}
사용.
const exitCode = await passthru('ls', ['-al'], { cwd: '/var/www/html' })
자식:
setInterval(function() {
process.stdout.write("hi");
}, 1000); // or however else you want to run a timer
상위:
require('child_process').fork('./childfile.js');
// fork'd children use the parent's stdio
저는 이 기능이 자주 필요하다는 것을 알게 되어 std-pour라는 라이브러리에 패키지화했습니다.명령을 실행하고 실시간으로 출력을 볼 수 있습니다.단순 설치 방법:
npm install std-pour
그런 다음 명령을 실행하고 실시간으로 출력을 볼 수 있을 정도로 간단합니다.
const { pour } = require('std-pour');
pour('ping', ['8.8.8.8', '-c', '4']).then(code => console.log(`Error Code: ${code}`));
여러 명령을 체인으로 연결할 수 있습니다.기능 서명 호환도 가능하므로 어디서나 교체할 수 있습니다.
에 대한 추가exec
저도 라이브 피드백이 필요했고 대본이 끝날 때까지 아무 것도 받지 못했기 때문입니다.exec
이벤트 이미터를 반환합니까?라는 많은 주장과 달리spawn
그런 식으로 작동합니다.
이것은 제가 수락된 답변에 대해 한 언급을 더 철저히 보완합니다.
exec의 인터페이스는 다음과 유사합니다.
// INCLUDES
import * as childProcess from 'child_process'; // ES6 Syntax
// DEFINES
let exec = childProcess.exec; // Use 'var' for more proper
// semantics, or 'const' it all
// if that's your thing; though 'let' is
// true-to-scope;
// Return an EventEmitter to work with, though
// you can also chain stdout too:
// (i.e. exec( ... ).stdout.on( ... ); )
let childProcess = exec
(
'./binary command -- --argument argumentValue',
( error, stdout, stderr ) =>
{ // When the process completes:
if( error )
{
console.log( `${error.name}: ${error.message}` );
console.log( `[STACK] ${error.stack}` );
}
console.log( stdout );
console.log( stderr );
callback(); // Gulp stuff
}
);
하는 것처럼 이벤트 핸들러를 등록할 수 .stdout
:
childProcess.stdout.on( 'data', data => console.log( data ) );
리고그.stderr
:
childProcess.stderr.on( 'data', data => console.log( `[ERROR]: ${data}` ) );
»pipe
기본 프로세스의 stdout에 대한 stdout:
childProcess.stdout.pipe( process.stdout );
전혀 나쁘지 않습니다 - HTH
저는 터미널에서 입력과 출력을 가져오는 스크립트를 실행하는 것에 관심이 있었고, 하위 스크립트가 완료되면 프로세스가 종료됩니다.
import { spawn } from 'node:child_process'
import process from 'node:process'
const script = spawn('path/to/script', { stdio: 'inherit' })
script.on('close', process.exit)
Python 3 스크립트를 생성할 때 위의 내용이 하나도 작동하지 않는 상황에 부딪혔습니다.나는 stdout에서 데이터를 얻지만, 아이가 종료된 후에만.
Python은 기본적으로 stdout을 버퍼링합니다.를 포함하여 할 수 -u
python3에 대한 명령줄 매개 변수로 사용됩니다.
언급URL : https://stackoverflow.com/questions/14332721/node-js-spawn-child-process-and-get-terminal-output-live
'programing' 카테고리의 다른 글
try-except 블록과 함께 python "with" 문 사용 (0) | 2023.07.25 |
---|---|
ANSI/VT100 코드를 사용한 PowerShell 콘솔의 컬러 텍스트 출력 (0) | 2023.07.25 |
오라클에서 날짜를 다른 형식으로 표시하는 방법 (0) | 2023.07.25 |
Android에서 ListView에 요소를 동적으로 추가하려면 어떻게 해야 합니까? (0) | 2023.07.25 |
Dunction2에서 SQL의 YEAR(), MONTH() 및 DAY()를 어떻게 사용할 수 있습니까? (0) | 2023.07.25 |