run-process.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/env node
  2. /**
  3. * run-process.js
  4. * 接收两个参数:ip 数组 (JSON)、脚本名
  5. * 异步根据每个 ip 执行脚本
  6. *
  7. * 调用示例:node run-process.js '["192.168.2.5","192.168.2.6"]' 'RedNoteAIThumbsUp'
  8. */
  9. const path = require('path')
  10. const fs = require('fs')
  11. const ipListJson = process.argv[2]
  12. const scriptName = process.argv[3]
  13. if (!scriptName) {
  14. process.stderr.write('run-process: missing scriptName\n')
  15. process.exit(1)
  16. }
  17. const folderPath = path.resolve(path.join(__dirname, '..', 'static', 'process', scriptName))
  18. function writeLog(folderPath, message) {
  19. const logFile = path.join(folderPath, 'log.txt')
  20. if (!fs.existsSync(folderPath)) fs.mkdirSync(folderPath, { recursive: true })
  21. const ts = new Date().toISOString().replace('T', ' ').slice(0, 19)
  22. fs.appendFileSync(logFile, `[${ts}] ${message}\n`)
  23. }
  24. try {
  25. writeLog(folderPath, `[run-process] start scriptName=${scriptName} folderPath=${folderPath}`)
  26. } catch (e) {
  27. process.stderr.write(`run-process: writeLog failed ${e.message}\n`)
  28. }
  29. let ipList
  30. try {
  31. ipList = JSON.parse(ipListJson || '[]')
  32. } catch (e) {
  33. writeLog(folderPath, `[错误] 解析 IP 列表失败: ${e.message}`)
  34. process.exit(1)
  35. }
  36. let shouldStop = false
  37. let actions
  38. try {
  39. const { parseWorkflow } = require('./ef-compiler/ef-compiler.js')
  40. actions = parseWorkflow(JSON.parse(fs.readFileSync(path.join(folderPath, 'process.json'), 'utf8'))).actions
  41. } catch (e) {
  42. writeLog(folderPath, `[错误] 加载 process.json 失败: ${e.message}`)
  43. process.exit(1)
  44. }
  45. const { executeActionSequence } = require('./ef-compiler/ef-compiler.js')
  46. const resolution = { width: 1080, height: 1920 }
  47. /** 启动执行:遍历 ip 列表并异步执行脚本;任一台失败则停止全部并返回失败设备 IP */
  48. async function start() {
  49. if (!ipList || ipList.length === 0) {
  50. writeLog(folderPath, '[run-process] 无设备,退出')
  51. process.stdout.write(JSON.stringify({ success: true, results: [] }) + '\n')
  52. process.exit(0)
  53. }
  54. writeLog(folderPath, `[run-process] 开始执行 ${ipList.length} 台设备: ${ipList.join(', ')}`)
  55. let failedIp = null
  56. const runOne = async (ip) => {
  57. if (shouldStop) return { ip, success: false, stopped: true }
  58. const result = await executeActionSequence(actions, `${ip}:5555`, folderPath, resolution, 1000, null, () => shouldStop)
  59. if (!result.success) {
  60. if (!failedIp) { failedIp = ip; shouldStop = true }
  61. }
  62. return { ip, success: result.success }
  63. }
  64. const results = await Promise.all(ipList.map(ip => runOne(ip)))
  65. const output = failedIp
  66. ? { success: false, failedIp, results }
  67. : { success: true, results }
  68. process.stdout.write(JSON.stringify(output) + '\n')
  69. process.exit(failedIp ? 1 : 0)
  70. }
  71. /** 停止执行(SIGTERM/SIGINT 时调用) */
  72. function stop() {
  73. shouldStop = true
  74. }
  75. process.on('SIGTERM', () => { stop(); process.exit(130) })
  76. process.on('SIGINT', () => { stop(); process.exit(130) })
  77. start()