为何Node.js中child_process.execSync需关闭Notepad窗口才结束?能否不使用异步函数规避该问题?
为何Node.js中child_process.execSync需关闭Notepad窗口才结束?能否不使用异步函数规避该问题?
这个问题我之前也碰到过,咱们一步步拆解原因,再给你不用异步函数的解决办法~
为什么会出现这个差异?
在你手动打开cmd窗口运行a.bat时,start "" notepad.exe其实是把Notepad“丢出去”单独运行的——相当于给系统发了个“启动Notepad”的指令,cmd自己该干嘛干嘛,执行完echo foobar就直接退出了,所以控制台窗口会关,但Notepad还留在后台。
但Node.js的execSync是个“死心眼”的同步调用:它会盯着自己启动的那个cmd进程,必须等这个cmd进程彻底“寿终正寝”才会继续往下走。而在非交互式的环境(也就是Node调用的cmd)里,start启动的Notepad会和cmd进程沾点“关系”——比如继承了一些IO句柄,导致cmd不敢先退出,得等Notepad关了、把这些“关系”断了,cmd才敢走,所以execSync就一直卡着,直到你关掉Notepad。
不用异步函数的解决办法
办法一:给你的bat文件加个“收尾命令”
只需要在a.bat最后加一行exit /b(或者直接exit),就能让cmd进程执行完所有命令后立刻跑路,不用等Notepad:
@echo off start "" notepad.exe echo foobar exit /b
这样execSync会在cmd退出时就拿到结果,Notepad该怎么跑怎么跑,互不耽误。
办法二:直接在execSync里调整命令
要是不想改bat文件,也可以直接把命令写得更“决绝”一点,让cmd启动Notepad后马上退出:
const child_process = require('child_process'); // 启动Notepad、输出foobar后立刻让cmd退出 console.log(child_process.execSync(`cmd /c "start "" notepad.exe && echo foobar && exit"`).toString());
额外小妙招:如果不需要捕获输出
要是你根本不在乎echo foobar的输出,还可以给execSync加个stdio参数,让它彻底不管cmd的IO,这样cmd会秒退:
const child_process = require('child_process'); child_process.execSync(`cmd /c a.bat`, { stdio: ['ignore', 'ignore', 'ignore'] }); // 这行代码执行完马上走下一步,Notepad已经在后台启动了
备注:内容来源于stack exchange,提问作者blz
相关产品推荐
相关产品推荐

