我正在使用,node.js v0.6.10尽管我在0.6.7. 基本上我运行一个子进程使用spawn启动另一个node.js的过程,并通过连通stdout和stdin 这里有两个脚本:
父 ( cli.js) :
var spawn = require("child_process").spawn;
var doSpawn = function(callback){
var child = spawn('child.js');
child.on('exit', function(code){
console.log("Child exited with code " + code);
});
child.stdin.write("ping");
child.stdin.end();
};
doSpawn();
setTimeout(function(){}, 10000);
Run Code Online (Sandbox Code Playgroud)
child.js
var run = function(){
process.stdout.on('drain', function(){
process.exit(0);
});
process.stdout.write(stdout);
};
var stdin = process.stdin;
stdin.resume();
stdin.setEncoding("utf8");
var stdout = '';
stdin.on('data', function(data){
stdout += data;
});
stdin.on('end', run);
Run Code Online (Sandbox Code Playgroud)
然后当我运行时node cli.js:
$ …Run Code Online (Sandbox Code Playgroud) 对于此处发布的代码长度,我深表歉意。我正在尝试创建一个类,该类使用 boost::process 来生成一个进程,在其 stdin 上为其提供一些数据并捕获其所有 stdout 和 stderr。
子进程的标准输入可能和标准输出一样冗长;目标机器没有大量内存,因此每个都需要分块处理。
我已经阅读了无数使用 boost::process 的例子,但没有发现任何可以一起回答所有这些问题的例子。我曾尝试将这些例子结合起来,但没有成功。我显然错过了一些东西。我将不胜感激任何帮助。
发生的情况是子进程成功生成但没有任何反应。父进程在标记为 THUS *的行上停止。
类定义:
class CommandProcessor {
public:
explicit CommandProcessor(const std::string &executable_path, bool slow) :
executable_path_(executable_path), slow_(slow), in_(io_service_, ::dup(STDIN_FILENO)), out_(io_service_, ::dup(STDOUT_FILENO)), err_(io_service_, ::dup(STDERR_FILENO)) {
}
private:
void begin_write_stdin();
void end_write_stdin(const boost::system::error_code &ec, std::size_t bytes_transferred);
void begin_read_stdout();
void end_read_stdout(const boost::system::error_code &ec, std::size_t bytes_transferred);
void begin_read_stderr();
void end_read_stderr(const boost::system::error_code &ec, std::size_t bytes_transferred);
public:
void execute_command(const Command& command);
private:
boost::filesystem::path executable_path_;bool slow_;
boost::asio::io_service io_service_;
boost::asio::posix::stream_descriptor in_;
boost::asio::posix::stream_descriptor out_;
boost::asio::posix::stream_descriptor err_; …Run Code Online (Sandbox Code Playgroud) 我的 nodejs 应用程序在接收特定请求时使用 spawn 生成一个子进程(我不能使用 exec,因为输出很大并且不知道我是否可以添加回调到生成的进程)来准备响应。
我希望子进程发送响应或主进程等待子进程准备响应并退出。
问题是主进程不等待子进程。
我已经编码了这样的东西
inputQuery: function(req, res){
var output="";
var query = "printjson(db.getCollectionNames())";
var temp = spawn("mongo", ["mongoweb ", "-eval", query]);
temp.on('error', function (err){
console.log(err);
});
temp.stdout.on('data', function(data){
output += data;
});
temp.stderr.on('data', function(data){
console.log(data);
});
temp.on("exit", function(code){
console.log("Output is :" + output);
res.send(output); // Either send response here or after the log message below
});
console.log("I want this to wait or let child respond");
}
Run Code Online (Sandbox Code Playgroud)
我真的被困住了,不知道该怎么做。请帮忙。提前致谢。
有没有办法在执行 child_process.spawn 时降低 stdout 的 highWaterMark?
我读到可能有一种方法可以为 exec 降低它,但我实际上需要启动一个进程,我可以通过 stdin 将数据传递到该进程并通过 stdout 读出结果。
highWaterMark 设置为 high 导致无法接受的读取标准输出延迟。
我试图将流对象传递给 spawn 链接:
avconv = spawn("avconv", params, {
stdio: [process.stdin, process.stdout, process.stderr]
});
Run Code Online (Sandbox Code Playgroud)
效果很好,但是当我尝试为女巫创建自己的流时,我可以定义一个自定义的 highWaterMark:
var readable = new stream.Readable();
avconv = spawn("avconv", params, {
stdio: [process.stdin, readable, process.stderr]
});
Run Code Online (Sandbox Code Playgroud)
节点不会接受它。导致类型错误。
用像这样的脚本
-- foo.hs
import System.Process
import Control.Concurrent
main = do
a <- runCommand "yes"
threadDelay 1000000
terminateProcess a
Run Code Online (Sandbox Code Playgroud)
我得到预期的行为 - yes一直运行直到threadDelay结束.但如果我替换"yes"为"runghc bar.hs"bar.hs的地方
import Control.Monad
import Control.Concurrent
main = forever (print 5 >> threadDelay 100000)
Run Code Online (Sandbox Code Playgroud)
...然后bar.hs永远运行.是否有更好的方法让runghc终止?
编辑: 此行为是在Linux上
我正在使用 Nodespawn创建一个新进程。有时,此过程会很快退出,并在 stderr 上显示错误代码和消息。似乎 stderr 在这种快速转变中迷失了方向。我试过这个:
reader.stderr.on('data', function (buf) {
console.log('stderr message: ' + buf);
});
reader.on('exit', function (code, signal) {
console.log('Exit');
});
Run Code Online (Sandbox Code Playgroud)
输出:
Exit
stderr message: ERROR: Missing required option for command.
Run Code Online (Sandbox Code Playgroud)
我也尝试在exit听众中阅读它,但没有运气:
reader.on('exit', function (code, signal) {
console.log('Exit');
console.log('stderr: ' + reader.stderr.read());
});
Run Code Online (Sandbox Code Playgroud)
输出:
Exit
stderr: null
Run Code Online (Sandbox Code Playgroud)
因此,问题似乎是 stderr 输出太慢,并且在我需要该信息的退出事件之后延迟。我怎样才能解决这个问题?
考虑以下代码:
import {spawn, exec} from 'child_process';
var child = spawn('su',
[process.env.USER, '-c', 'while (true); do sleep 0.3; echo "tick"; done'],
{stdio: ['ignore', 'pipe', 'pipe']}
);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
setTimeout(() => {
child.kill();
}, 1000);
Run Code Online (Sandbox Code Playgroud)
在这里,我试图运行运行其他一些子进程的特定脚本(在该示例su中将产生一个bash进程)并关闭它。但是,我无法让它按我的预期工作。
调用child.kill()只会杀死 的父进程,su而不是它的子进程bash。
可以做些什么来使其工作 - 调用exec(`pkill -TERM -P ${child.pid}`)而不是child.kill(). 据我了解,这将杀死父进程的整个进程树child.pid。
然而,当将两种方法结合在一起时,它有一些奇怪的地方:
setTimeout(() => {
child.kill();
exec(`pkill -TERM -P ${child.pid}`);
}, 1000);`
Run Code Online (Sandbox Code Playgroud)
tick即使在进程被终止后,此代码也会继续写入控制台。
为什么会发生这种情况?有人可以解释一下吗?
在我的(cmd.exe)中,当前工作目录是名为libre-office-document.odt的文件.我可以使用start命令打开此文档而不会出现问题:
c:\path\to\> start libre-office-document.odt
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用以下简单的Perl脚本
use warnings;
use strict;
print system("start libre-office-document.odt")
Run Code Online (Sandbox Code Playgroud)
并在同一目录中执行它,我得到以下消息框:
LibreOffice 4.4 - 致命错误
该应用程序无法启动.
用户安装无法完成.
显然,使用Perl system命令时某些行为会有所不同.我无法确定这是什么以及如何使用该system命令打开文档.
我正在使用 child_process.spawn() 生成一个进程。如何查看执行的确切命令行(包括传递给 spawn 函数的所有命令行参数)?
这是我不起作用的示例:
var s = require('child_process');
var p = s.spawn('ffmpeg', ['-probesize 1024', '-i "rtsp://192.168.1.10:554/11"', 'test.h264']);
Run Code Online (Sandbox Code Playgroud)
当我捕获标准错误时,我收到一条消息“无法识别的选项 'probesize 1024'。但是,如果我从命令行运行 ffmpeg,它工作正常。所以我需要在被修改之前确切地查看命令行选项是如何被破坏的发送到 FFMPEG 以进行调试。
谢谢
我在 Windows 10 上使用 Nodejs。每次打开应用程序时,我都想检查带有扩展名的文件ext是否与我的应用程序相关联。如果不是,我将需要在 cmd 上运行此命令以再次建立关联:
assoc .ext=CustomExt
ftype CustomExt=app.exe %1 %*
Run Code Online (Sandbox Code Playgroud)
但是我需要管理员权限才能完成这项工作。
我读过这个帖子,Jeff M 准确地说出了我想要实现的目标,但没有人回答他:
从可用性的角度来看,理想的情况是,只有当用户在我的节点程序中执行实际需要这些权限的操作时,才会提示用户提升权限。在第二个最好的选择是,如果用户被提示输入提升的权限时,他们首先启动节点计划。最不理想的是,如果根本没有提示用户,则由用户始终记住通过右键单击以管理员身份运行来启动程序。这是最不理想的,因为它会给用户带来负担,要记住始终以非典型方式启动程序。
因此,回到我原来的问题,现在如果我尝试生成一个子进程,其中生成的程序需要提升的权限(原始消息中的示例代码),当前的行为是不会提示用户输入这些权限,而是节点程序因错误而崩溃。我怎样才能让我的节点程序请求这些特权而不是死掉?
我的 nodejs 脚本:
const { spawn } = require('child_process');
const assoc = spawn( // how to run this as admin privileges?
'assoc', // command
['.ext=CustomExt'], // args
{'shell': true } // options: run this into the shell
);
assoc.stdout.on('data', (buffer) => {
var message = buffer.toString('utf8');
console.log(message);
});
assoc.stderr.on('data', …Run Code Online (Sandbox Code Playgroud)