You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js如何先spawn子进程,之后向运行中进程传参执行命令(Mac环境)

实现方案

原代码失效原因

  • 直接启动不带参数的osascript进程时,标准输入接收的是可直接执行的AppleScript代码,而非脚本文件路径,直接写入文件名无法被识别为执行指令
  • 写入内容后没有添加换行符\n,osascript会认为输入还未结束,一直等待后续输入,不会触发执行
  • 未监听子进程的stdout、stderr输出,会导致输出缓冲区溢出后子进程被阻塞,同时无法排查潜在报错

可运行实现代码

如果需要复用同一个osascript子进程,多次触发执行不同的脚本文件,可参考如下写法:

const { spawn } = require('child_process');
const path = require('path');

// 启动osascript交互子进程
const osascriptProc = spawn('osascript', [], {
  cwd: __dirname, // 按需调整工作目录,避免脚本路径匹配问题
});

// 必须监听子进程输出和错误,避免缓冲区溢出导致进程卡住
osascriptProc.stdout.on('data', data => {
  console.log('执行输出:', data.toString());
});
osascriptProc.stderr.on('data', data => {
  console.error('执行错误:', data.toString());
});
osascriptProc.on('close', code => {
  console.log('子进程退出,退出码:', code);
});

// 触发执行指定scpt脚本的方法
function execScptFile(fileName) {
  // 构造执行外部脚本的AppleScript指令,末尾加换行触发执行
  const execCmd = `run script POSIX file "${path.resolve(__dirname, fileName)}"\n`;
  osascriptProc.stdin.write(execCmd);
}

// 测试:延迟1秒后触发执行脚本
setTimeout(() => {
  execScptFile('script-test.scpt');
  // 若后续不需要再执行任何脚本,可调用end方法关闭标准输入,让子进程正常退出
  // osascriptProc.stdin.end();
}, 1000);

注意事项

  • 脚本路径尽量使用绝对路径,避免工作目录不匹配导致找不到文件
  • 每次写入执行指令必须末尾加\n,否则osascript不会触发执行
  • 如果不需要复用子进程,直接在spawn的第二个参数传入脚本路径即可,不需要通过stdin写入:spawn('osascript', ['script-test.scpt'])

内容的提问来源于stack exchange,提问作者SeanRtS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:06:03