简体   繁体   English

如何显示从Node JS服务器到客户端的Shell脚本结果?

[英]How to display result of shell script from node js server to the client?

I have a node js server, which triggers a shell script that I have. 我有一个节点js服务器,它触发了我拥有的shell脚本。 The code is as follows (simple Hello World example): 代码如下(简单的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.");

The code works perfectly - A server is started and whenever the page is loaded (request) in the browser, the shell script runs on the server and outputs its results on the terminal. 代码完美运行-启动服务器,每当在浏览器中加载页面(请求)时,shell脚本就会在服务器上运行,并在终端上输出结果。

Now, I want to display that result back to the client browser instead of just "Hello World". 现在,我想将该结果显示回客户端浏览器,而不仅仅是“ Hello World”。 How to do that? 怎么做? Please note that the script takes 4 - 5 seconds to execute and generate a result. 请注意,脚本需要4到5秒钟来执行并生成结果。

You have two options: 您有两种选择:

Option 1: 选项1:

Convert your function to use the child_process.exec method instead of child_process.spawn method. 将函数转换为使用child_process.exec方法而不是child_process.spawn方法。 This will buffer all data sent to stdout in memory and allow you to send as one chunk across the line to the browser: 这将把所有发送到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.");
});

Option 2: 选项2:

If you want to keep the child_process.spawn method, you will need to introduce real time networking into your stack that pushes data events to the browser upon receiving events from the child process. 如果要保留child_process.spawn方法,则需要在堆栈中引入实时网络,以便在从子进程接收事件时将数据事件推送到浏览器。 Take a look at socket.io or (recommended) SockJS for setting up real time communication between your server and client. 查看socket.io或(推荐)SockJS,以在服务器和客户端之间建立实时通信。

Side Note: 边注:

I wanted to point out a flaw in your code above that will end up hurting you in the long run in your future endeavors with node. 我想指出上面的代码中的一个缺陷,从长远来看,这最终会伤害到您将来对节点的努力。

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

  var spawn = require('child_process').spawn;

In the last line above, you are requiring the child_process module on each request. 在上面的最后一行中,您需要在每个请求上使用child_process模块。 Not only does this add unnecessary overhead to each request, you will end up running into module caching issues if you are not careful. 这不仅会给每个请求增加不必要的开销,而且如果您不小心的话,最终会遇到模块缓存问题。 It is recommended that all calls to require happen at the top of the module scope and no where else. 建议所有对require的调用都发生在模块作用域的顶部,而不是其他地方。 The only time its "acceptable" to make require calls in the middle of your logic is when building truly synchronous CLI tools — but even then its best to keep all requires organized at the top of your module scope for readability. 只有在构建真正的同步CLI工具时,它的“可接受”调用逻辑中的唯一一次了–但是即使如此,最好还是将所有需求组织在模块范围的顶部,以提高可读性。

 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM