Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 尝试在node.js中执行shell脚本的同步行为_Javascript_Node.js_Shell - Fatal编程技术网

Javascript 尝试在node.js中执行shell脚本的同步行为

Javascript 尝试在node.js中执行shell脚本的同步行为,javascript,node.js,shell,Javascript,Node.js,Shell,我对node.js很陌生,我将它用作服务器来接收http。从浏览器获取请求,进行一些处理并将结果返回到浏览器 处理过程实际上是使用phantom.js/casper.js抓取一个网站,由于在node.js中使用casper.js的复杂性,我使用shell脚本将其作为子进程执行 当我运行下面的代码并从浏览器发出请求时,响应似乎出现在shell脚本运行之前。我尝试使用异步库以串联方式运行步骤,以便run.sh在添加到响应之前运行并返回一个值,但它似乎不是这样工作的。有人能看出我的愚蠢错误吗 提前谢谢

我对node.js很陌生,我将它用作服务器来接收http。从浏览器获取请求,进行一些处理并将结果返回到浏览器

处理过程实际上是使用phantom.js/casper.js抓取一个网站,由于在node.js中使用casper.js的复杂性,我使用shell脚本将其作为子进程执行

当我运行下面的代码并从浏览器发出请求时,响应似乎出现在shell脚本运行之前。我尝试使用异步库以串联方式运行步骤,以便run.sh在添加到响应之前运行并返回一个值,但它似乎不是这样工作的。有人能看出我的愚蠢错误吗

提前谢谢

var express = require('express');
var app = express();
var sys = require('sys');
var exec = require('child_process').exec;
var async = require('async');
var auth = express.basicAuth('test', 'pass');
var server = app.listen(3000, function() {
    console.log('Listening on port %d', server.address().port);
});
var result;


//app.use(auth);

app.get('/free/:u/:p', auth, function(req, res) { 
    async.series([
        function(callback){
            var puts = function (error, stdout, stderr) {
                result = stdout;
             }
             exec("./run.sh " + req.params.u + " " + req.params.p, puts);
             callback(null);
        },
        function(callback){
             res.writeHead(200,{'Content-Type':'application/json'});
             res.send(result)
             callback(null);
        }
    ]);
});

app.get('/', function(req, res) {
  res.send('Hello!');
});
您没有异步调用callbacknull。你需要把它放进去

此外,您不应该使用全局结果变量—它甚至在请求之间是全局的,可能会将数据泄漏到不同的客户端—arghh!。对于这个微不足道的链,几乎没有理由使用async.js

app.get('/free/:u/:p', auth, function(req, res) { 
    exec("./run.sh " + req.params.u + " " + req.params.p, function (error, stdout, stderr) {
       res.writeHead(200,{'Content-Type':'application/json'});
       res.send(stdout);
    });
});

请注意不转义shell参数所带来的安全问题。

基本上,您遇到的问题是,调用exec时就像调用同步函数一样,而实际上它是异步的

因此,你实际上应该:

exec("./run.sh " + req.params.u + " " + req.params.p, puts, function(){
   callback(null);
});
或者简单地这样做,因为无论如何,您不必关心异步系列中的函数传递的函数参数

exec("./run.sh " + req.params.u + " " + req.params.p, puts, callback)

原因是您运行shell命令,然后立即调用回调,该回调运行响应的下一个函数

要修复它,您可以像这样更改puts函数puts并删除callbacknull:


虽然这种方法有效,但最好使用async.瀑布而不是async.series。它允许您将每个函数的结果传递给下一个函数。因此,您不需要全局结果变量。

感谢您的帮助advncd,这也很有效,但我想我使用的是不必要的async Ryperfect,与此相比,我的代码真的很差!现在我有一个不同的问题,它只有在注释掉res.writeHead部分时才会运行。它似乎在写头前运行send。这是我得到的错误:错误:发送邮件后无法设置邮件头。还有-你提到的安全问题是什么-我有点迷路了..嗯,不应该。代码中还有其他发送吗?我所说的脆弱性是一个基本问题。浏览/免费//rm+-r+\。或者更好:不要!除上述“/”路线代码外,不读取代码中的其他发送。。我理解为什么现在这是一个巨大的安全问题!有道理。不过,我并没有真正理解逃跑的解决方案。我是否需要使用某种正则表达式来排除可能意外执行的任何内容?不,您需要将字符串参数用引号括起来,并使用正则表达式来转义任何字符串分隔符。或者您只需使用spawn而不是exec,exec会接受一系列参数并适当地转义它们。好的,谢谢。因此,从我读到的内容来看,spawn发回一个数据流,而不是在使用exec时将其限制在缓冲区大小。我找不到关于shell参数自动转义的任何资料。此外,我还必须捕获流,这将使我回到最初的异步问题。。。啊。你有没有可能改用spawn为我重写上面的内容?
var express = require('express');
var app = express();
var sys = require('sys');
var exec = require('child_process').exec;
var async = require('async');
var auth = express.basicAuth('test', 'pass');
var server = app.listen(3000, function() {
    console.log('Listening on port %d', server.address().port);
});
var result;


//app.use(auth);

app.get('/free/:u/:p', auth, function(req, res) { 
    async.series([
        function(callback){
            var puts = function (error, stdout, stderr) {
                result = stdout;
                callback(null); //added here
             }
             exec("./run.sh " + req.params.u + " " + req.params.p, puts);
             //callback(null);  //commented
        },
        function(callback){
             res.writeHead(200,{'Content-Type':'application/json'});
             res.send(result)
             callback(null);  
        }
    ]);
});

app.get('/', function(req, res) {
  res.send('Hello!');
});