从 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 并帮助我,我将不胜感激。
将backups
和site
移动到传递给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
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 并帮助我,我将不胜感激。
将backups
和site
移动到传递给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