由于(可能)错误的bash脚本而导致一些奇怪的错误

时间:2019-07-04 11:28:16

标签: javascript html bash

我面临一些奇怪的错误。我正在使用一个查询引擎界面,在该界面上,用户应以以下形式查询:(Sub,Pred,Obj),其中Sub,Pred和Obj是资源(如在RDF中)。如果用户希望获得与给定Pred和Obj匹配的Sub,那么他将查询(?, Pred,Obj)。那么,?指示用户希望获得什么输出(我们可以有多个?)。 现在,在我的网页上,我尝试了所有8种组合,但是只有1种无法显示任何输出。此组合为(?, Something,?)。我有一个bash脚本,单击一个按钮即可以正确的查询格式调用我的C代码(即我的查询引擎)。它将查询的输出存储在文件中。现在,脚本中的另一个命令将运行另一个bash命令,该命令将创建一个网页,该网页包含无序列表形式的输出的每一行。现在,当我提出有问题的查询(即(?, Something,?))时,该文件包含正确的输出,但是bash脚本无法创建正确的网页。

//BashScript (create_q_out_list.sh) to create the web-page from data
function createPage
{
    filename='temp'                                 
    outfile='q_out_list.html'   
    echo "<html>" > $outfile
    echo "<head>" >> $outfile
    echo "<title>" >> $outfile
    echo "List of Query Results" >> $outfile
    echo "</title>" >> $outfile
    echo "</head>" >> $outfile
    echo "<body>" >> $outfile
    echo "<ul>" >> $outfile
    IFS=$'\n'           
    while read line #Loop to go through each relation in the file
    do
        echo "<li>$line</li>" >> $outfile
        echo $line
    done < $filename
    echo "</ul>" >> $outfile
    echo "</body>" >> $outfile
    echo "</html>" >> $outfile
}

createPage $@
// JavaScript file that calls the above script and my querying engine to
// generate web-page and the file containing the output of the query respectively

var exec = require("child_process").exec;
function query(type, sub, pred, obj) {
  if (type === "Search")
    str = './search "<' + sub + "," + pred + "," + obj + '>" > temp';
  if (type === "Create")
    str = './create "<' + sub + "," + pred + "," + obj + '>" > temp';
  if (type === "Delete")
    str = './delete "<' + sub + "," + pred + "," + obj + '>" > temp';
  exec(str, function(error, stdout, stderr) {
    console.log("stdout:" + stdout);
    console.log("stderr:" + stderr);
    if (error != null) {
      console.log("exec error: " + error);
    }
  });
  exec("bash create_q_out_list.sh", function(error, stdout, stderr) {
    console.log("stdout:" + stdout);
    console.log("stderr:" + stderr);
    if (error != null) {
      console.log("exec error: " + error);
    }
  });
}

module.exports.query = query;

在上面的代码中,temp是包含输出的文件。同样,q_out_list.html是应该作为运行create_q_out_list.sh的输出而生成的网页。 现在,除了我上面描述的一种以外,所有组合的两个脚本都运行良好。但是对于这种组合,查询引擎仍会给出正确的输出,即temp文件包含正确的输出。但是生成的网页没有临时文件的任何信息。

2 个答案:

答案 0 :(得分:1)

您的JavaScript代码在继续执行exec调用之前不会等待第一个bash完成。

有两种方法可以解决此问题:

  • 改为使用execSync –这很简单,但是会在子进程执行时阻止Node.js进程
  • 将第二个exec()调用放入第一个exec()的回调中(下面的示例1)
  • 使用async / await和约定的exec() –这更干净,更好(下面的示例2 –以及其他现代化)。

示例1

var exec = require("child_process").exec;
function query(type, sub, pred, obj) {
  if (type === "Search")
    str = './search "<' + sub + "," + pred + "," + obj + '>" > temp';
  else if (type === "Create")
    str = './create "<' + sub + "," + pred + "," + obj + '>" > temp';
  else if (type === "Delete")
    str = './delete "<' + sub + "," + pred + "," + obj + '>" > temp';
  else throw new Error("Invalid type");
  exec(str, function(error, stdout, stderr) {
    console.log("stdout:" + stdout);
    console.log("stderr:" + stderr);
    if (error != null) {
      console.log("exec error: " + error);
      return;
    }
    exec("bash create_q_out_list.sh", function(error, stdout, stderr) {
      console.log("stdout:" + stdout);
      console.log("stderr:" + stderr);
      if (error != null) {
        console.log("exec error: " + error);
      }
    });
  });
}

示例2

var exec = require('child_process').exec;
var promisify = require('util').promisify;
var execP = promisify(exec);

const typeToBinary = {
  Search: './search',
  Create: './create',
  Delete: './delete',
};

async function query(type, sub, pred, obj) {
  const binary = typeToBinary[type];
  if (!binary) {
    throw new Error(`Invalid type ${type}`);
  }
  var command = `${binary} "<${sub},${pred},${obj}>" > temp`;
  const [stdout1, stderr1] = await execP(str);
  const [stdout2, stderr2] = await execP('bash create_q_out_list.sh');
  console.log(stdout1, stderr1, stdout2, stderr2);
}

答案 1 :(得分:0)

read语句缺少一个-r标志,以防止其内容扩展。

#!/usr/bin/env bash

# create_q_out_list.sh to create the web-page from data

function createPage
{
  filename='temp'
  outfile='q_out_list.html'

  li_results="$(
  # read without -r will mangle backslashes
  # see https://github.com/koalaman/shellcheck/wiki/SC2162
    while read -r line || [[ ${line} ]]
    # Loop to go through each relation in the file
    # The || [[ ${line} ]] will allow entering the loop
    # even when the last line ends EOF, causing read to return false,
    # rather than with a newline character
    do
        echo "      <li>${line}</li>"
    done < "${filename}"
  )"

  cat >"${outfile}" <<EOF
<!DOCTYPE HTML>
<html>
  <head>
    <title>List of Query Results</title>
  </head>
  <body>
    <ul>
${li_results}
    </ul>
  </body>
</html>
EOF
}

# Double quote array expansions to avoid re-splitting elements.
# See: https://github.com/koalaman/shellcheck/wiki/SC2068
createPage "$@"