我目前正在为git开发web界面。通过child_process.spawn访问git本身。虽然有简单的"命令->响应"机制,但一切都很好,但我不明白应该如何处理命令提示(例如git fetch
要求输入密码)。假设有一些事件被触发,但我不知道该听什么。我看到的只是node.js进程本身运行的命令行中的"git_user@myserver's password: _
"。
将这个请求重定向到我的web应用程序中会很好,但这可能吗?
我已经尝试在所有流(stdout、stdin、stderr)上侦听message
、data
、pipe
、end
、close
、readable
,但没有人在密码提示下触发。
这是我的工作解决方案(没有提到实验):
var out="";
var err="";
var proc=spawn(exe,cmd);
proc.on("exit",function(exitCode){
});
proc.stdout.on("data",function(data){
out+=data;
});
proc.stderr.on("data",function(data){
err+=data;
});
proc.on("close",function(code){
if(!code)func(out);
else return errHandler(err);
});
你能帮我调查一下吗?
更新
当前情况:在我的GIT web界面上有一个按钮"FETCH"(例如,简单的"GIT FETCH")。当我按下它时,会生成http请求,并将其发送到http.createServer(callback).listen(8080)
创建的node.js服务器。callback
函数接收我的请求并创建child_process.spawn('git',['-C','path/to/local/repo','fetch'])
。一直以来,我在web界面上只看到加载屏幕,但如果我切换到运行节点脚本的命令行窗口,我会看到密码提示。现在让我们假设我不能将窗口切换到控制台,因为我是远程工作的。
我想在我的网页界面上看到密码提示。例如,如果child_process在提示用户输入时会在child.stdin
(或其他地方)上发出一些事件,那么这将非常容易实现。在这种情况下,我会将字符串"来吧,伙计,git想知道你的密码!在这里输入:_______"发送回web客户端(通过response.end(str)
),并继续等待客户端响应的下一个http连接,其中包含所需的密码。然后简单地child.stdin.write(pass)
它到git的过程。
这个解决方案可能吗?或者不涉及父进程的命令行。
更新2
只是尝试将侦听器附加到官方文档中描述的所有可能的事件:stdout和stderr(可读、数据、结束、关闭、错误)、stdin(排出、完成、管道、取消管道、错误)和child(消息、退出、关闭、断开连接、消息)。
在管道传输git流后,在process.stdout和process.stderr上尝试了相同的侦听器。
密码请求未触发任何内容。。。
您的代码无法工作的主要原因是,您只会发现Git进程在执行之后发生了什么。
使用派生的主要原因是因为可以配置派生的进程,而stdout和stderr是父进程中的可读流。
我刚刚试用了这个代码,效果很好。下面是一个生成进程以执行git推送的示例。然而,正如您所知,git会要求您提供用户名和密码。
var spawn = require('child_process').spawn;
var git = spawn('git', ['push', 'origin', 'master']);
git.stderr.on('data', function(data) {
// do something with it
});
git.stderr.pipe(process.stderr);
git.stdout.pipe(process.stdout);
- 制作一个本地git repo并进行设置,以便您可以执行上述推送命令。但是,您确实可以执行任何git命令
- 将其复制到一个名为git_process.js的文件中
- 使用节点git_process.js运行
不知道这是否有帮助,但我发现拦截子进程提示的唯一方法是在生成新的子进程时将分离选项设置为true。
和你一样,我在interwebs的节点中找不到任何关于子进程提示的信息。人们可能会怀疑它应该进入stdout,然后您就必须写入stdin。如果我没有记错的话,您可能会发现提示被发送到stderr。
其他人没有遇到这个问题,这让我有点惊讶。也许我们只是做错了。