如何从节点js服务器向客户端显示shell脚本的结果?

我有一个节点js服务器,它触发我有一个shell脚本。 代码如下(简单的Hello World例子):

var http = require("http"); function onRequest(request, response) { console.log("Request received."); response.writeHead(200, {"Content-Type": "text/plain"}); var spawn = require('child_process').spawn; //executes my shell script - main.sh when a request is posted to the server var deploySh = spawn('sh', [ 'main.sh' ]); //This lines enables the script to output to the terminal deploySh.stdout.pipe(process.stdout); //Simple response to user whenever localhost:8888 is accessed response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); 

代码完美工作 – 服务器启动,并且在浏览器中加载页面(请求)时,shell脚本将在服务器上运行并在terminal上输出其结果。

现在,我想将结果显示回客户端浏览器,而不是“Hello World”。 怎么做? 请注意脚本需要4 – 5秒才能执行并生成一个结果。

你有两个select:

选项1:

将您的函数转换为使用child_process.exec方法而不是child_process.spawn方法。 这将caching发送到内存中的stdout所有数据,并允许您作为一个块跨越线路发送到浏览器:

 var http = require("http"), exec = require("child_process").exec; function onRequest(request, response) { console.log("Request received."); response.writeHead(200, {"Content-Type": "text/plain"}); //executes my shell script - main.sh when a request is posted to the server exec('sh main.sh', function (err, stdout, stderr) { if (err) handleError(); //Print stdout/stderr to console console.log(stdout); console.log(stderr); //Simple response to user whenever localhost:8888 is accessed response.write(stdout); response.end(); }); } http.createServer(onRequest).listen(8888, function () { console.log("Server has started."); }); 

选项2:

如果您想保留child_process.spawn方法,则需要将实时networking引入到堆栈中,以便在收到来自subprocess的事件时将数据事件推送到浏览器。 看看socket.io或(推荐)SockJS来build立您的服务器和客户端之间的实时通信。

边注:

我想在上面的代码中指出一个缺陷,那就是在未来的节点努力中,最终会伤害到你。

 function onRequest(request, response) { console.log("Request received."); response.writeHead(200, {"Content-Type": "text/plain"}); var spawn = require('child_process').spawn; 

在上面的最后一行中,您需要每个请求上的child_process模块。 这不仅会给每个请求增加不必要的开销,如果不小心的话,最终会遇到模块caching问题。 build议所有需要的调用都发生在模块范围的顶部,而不是在其他地方。 唯一一次它的“可接受的”要求在你的逻辑中调用的时候是在构build真正的同步CLI工具的时候 – 但是尽pipe如此,尽可能地把所有的需求组织在模块范围的顶部以便于阅读。

  var http = require('http'), process = require('child_process'); var server = http.createServer(function (req,res){ res.writeHead(200,{'content-type':'text/html'}); process.exec('ls',function (err,stdout,stderr) { if(err){ console.log("\n"+stderr); res.end(stderr); } else { console.log(stdout); res.end("<b>ls displayes files in your directory</b></br>"+stdout+"</br>"); } }); }).listen(3000);