Какая-то странная ошибка из-за (возможно) ошибочного сценария bash - PullRequest
1 голос
/ 04 июля 2019

У меня странная ошибка. Я работаю над интерфейсом механизма запросов, где пользователь должен задавать запросы вида (Sub, Pred, Obj) , где Sub, Pred и Obj - ресурсы (как в RDF). Если пользователь хочет получить соответствующие Sub с данными Pred и Obj, он запросит (?, Pred, Obj) . Так, ? указывает, что пользователь хочет получить в качестве вывода (мы можем иметь несколько?). Сейчас на моей веб-странице я перепробовал все 8 комбинаций, но только 1 не отображает вывод. Это комбинация (?, Что-то,?) . У меня есть скрипт 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. Теперь оба сценария работают хорошо для всех комбинаций, кроме той, что я описал выше. Но для этой комбинации механизм запросов по-прежнему дает правильный вывод, то есть временный файл содержит правильный вывод. Но сгенерированная веб-страница не содержит никакой информации о временном файле.

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Ваш код 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);
}
0 голосов
/ 04 июля 2019

В операторе 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 "$@"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...