从 spawnSync 到 express-handlebars 的标准输出

Stdout from spawnSync to express-handlebars

Node 新手,请多多包涵。 我也知道之前有人问过这个问题,但我还没有弄清楚如何在我的案例中使用它,所以请再次尝试提供帮助。

我想做的 - 尝试使用 express-handlebars 以列表格式获取特定 docker 容器的图像。

代码-

app.get('/restore/:userid', async (req,res) => {
  let userid = req.params.userid
  let userData = await Users.findById(userid, async function(err, data) {
    let site = await data.docker.site.slice(8)
    let backupsRun = await spawnSync('sh', ['-c', `echo redhat237 | sudo -S docker images | grep ${site} | awk '{print }'`], {encoding: 'utf-8'})
    let backupsStdout = await backupsRun.stdout
    if (backupsRun.status != 0) {var getBackups = new Error("Cannot fetch Backups")}
    let backupsStdoutDecoded = await unescape(encodeURIComponent(backupsStdout))
    let backupsArr = await backupsStdoutDecoded.split("\n")
    /*for (var i = 0; i < backupsArr.length; i++) {
      var backups = await backupsArr[i].value
    }*/
    let backups = backupsArr
    try {
      console.log(backups + ' Try Block')
      await res.render('restore', {
        helpers: {
          userid: function () {return req.params.userid},
          site: site,
          backups: backups
        }
      })
    } catch (e) {
      if (e.getBackups) {
        res.send(e.getBackups)
      } else {
        res.send(e)
      }
    }
  })
}) //close restore get

我可以在 console.log 中看到输出,但它显示为 1 行,看似有 1 个索引。

test.test.org-12-7-2021T12_13,test.test.org-12-07-21T12_10,test.test.org12-07-21T12_10,test.test.org, Try Block

我的车把页面 -

<h1>Restore for {{site}} - </h1>
<ul>
  {{#each backups}}
  <li><p>{{this}}</p></li>
  {{else}}
  <h3>ERROR - No Backups or we couldn't retrieve your backups</h3>
  {{/each}}
</ul>
<div>
  {{backups}} - Backups array in div
</div>

奇怪的是我可以在我为调试添加的 div 部分看到输出,但是我无法让 #each 块迭代。

从我从以下情况中可以理解的是,虽然 split() 应该 return 由于某种原因似乎没有发生的子字符串数组。

我什至去尝试了 join() 和 toString() 但结果是一样的。 如果我取消注释 for 循环和 运行 它与 .value 它 returns "undefined" in the console.log.

如果有人可以指出我的 mistake/s 并帮助我,我将不胜感激。

backupssite移动到传递给res.render

的父对象
res.render('restore', {
  helpers: {
    userid: function () {return req.params.userid},
  },
  site,
  backups,
  })

然后循环变量`{{#backups}}

<h1>Restore for {{site}} - </h1>
<ul>
  {{#each backups}}
  <li><p>{{this}}</p></li>
  {{else}}
  <h3>ERROR - No Backups or we couldn't retrieve your backups</h3>
  {{/each}}
</ul>
<div>
  {{ backups }} - Backups array in div
</div>

更多清理工作

当数组转换为字符串时,它们用 , 连接。 console.log(backups + ' Try Block') 正在进行此转换。

允许应用程序用户通过 sudoers 无需密码即可访问 运行 sudo docker images(或者,如果必须,sudo docker,但了解应用已完成的 security implications现在控制主机)

避免在执行命令时使用 shell。使用 dockers 过滤器和输出修饰符或尽可能在 JS 中处理输出。

仅在调用 async 函数时使用 await

为 运行 你的 docker 命令设置一个异步函数,假设这可能很常见。

const util = require('util')
const exec = util.promisify(require('child_process').exec)

async function dockerCommand(docker_args) {
  try {
    console.log('Running docker', docker_args)
    const res = await exec(['sudo', 'docker', ...docker_args])
    return res
  } catch (e) {
    console.error('Error running docker', docker_args, e)
    throw e
  }
}
app.get('/restore/:userid', async (req, res) => {
  try {
    const userid = req.params.userid
    const userData = await Users.findById(userid)
    const site = userData.docker.site.slice(8)
    const { stdout, stderr } = await dockerCommand('images', `--filter=*:${site}*`, '--format={ .Tag }')
    const backups = stdout.split('\n')
    console.log('backups for site[%s]', site, backups)
    res.render('restore', {
      helpers: {
        userid: function () {return req.params.userid},
      },
      site,
      backups,
    })
  } catch (e) {
    console.error('Error retrieving backups', req.params.userid, e)
    res.send('Error retrieving backups')
  }
}) //close restore get