以下内容在win10环境下的执行分析(这里就不对进程和线程做区分了):
child_process.exec
和child_process.spawn
启动进程的区别。
shell <string> Shell to execute the command with. See Shell requirements and Default Windows shell. Default: '/bin/sh' on Unix, process.env.ComSpec on Windows.
> shell <string> 使用shell执行命令。请参阅外壳要求和默认Windows外壳。默认值:Unix上的“/bin/sh”,process.env。Windows上的ComSpec。
shell <boolean> | <string> If true, runs command inside of a shell. Uses '/bin/sh' on Unix, and process.env.ComSpec on Windows. A different shell can be specified as a string. See Shell requirements and Default Windows shell. Default: false (no shell).
> shell <boolean> | <string> 如果为true,则在shell内运行命令。在Unix上使用'/bin/sh'和process.env。Windows上的ComSpec。可以将其他shell指定为字符串。请参阅shell要求和默认Windows shell。默认值:false(无shell)。
child_process.exec
启动的进程是先启动cmd命令,在把你通过exec传入的command字符串放到cmd中执行,
这样就会导致有2个进程,1个是进程是cmd命令所启动的,另一个进程是你传入的command命令所启动的。
这就会导致你通过exec获取到的进程实例其实是cmd进程的PID,而cmd进程所启动的命令的进程你是获取不到的,
自然就无法通过kill停止了,因为你停止的只是cmd进程,而不是你传入执行的command字符串命令所在的进程。
正是因此,所以exec适合短时间运行的命令任务,例如dir
,tasklist
等这种会自己结束的命令。
而child_process.spawn
命令默认是不在shell中执行,因为shell的默认值是false吗!这里我们举一个spawn
命令的例子来说明怎么使用。
const ls = spawn('C:\\Windows\\System32\\PING.EXE', ['-n 600 127.0.0.1'], {
shell: false,
windowsVerbatimArguments : true,
});
ls.stdout.on('data', (data) => {
debugger
console.log(`stdout: ${iconv.decode(data, 'gbk')}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process close exited with code ${code}`);
});
ls.on('exit', (code) => {
console.log(`child process exited with code ${code}`);
});
// 2分钟后停止子进程。
setTimeout(()=>{
let kill = ls.kill();
console.log("模仿主进程停止,停止子进程成功?" + kill);
}, 1000 * 60 * 2)
spawn
命令的参数我这里简单说明下,详细的看Nodejs官方文档,
spawn
命令的第一个参数是要执行的命令的完整路径(不要携带参数,否则会执行报错,提示找不到命令),
spawn('C:/a/b/c.exe -n 100')
这种使用就是错误的,正确的使用方式是spawn('C:/a/b/c.exe')
这种方式。
而第二个参数是要提供一个String[]字符串数组,但是这个数组有2种传值的方式。
第一种方式是['-n 100'],如果你传入这个参数,当前spawn执行的命令进程会执行后就会瞬间退出,因为命令对这个参数无法解析,这主要是nodejs对命令的参数解析后,
在实际执行的时候参数就不认识了,但是当你配置上windowsVerbatimArguments参数为true值,就可以解决这个解析参数的问题。
windowsVerbatimArguments
在Windows上不进行参数的引用或转义。在 Unix 上被忽略。当指定 shell 且为 CMD 时,此值自动设置为 true。默认值:false。
完整的例子:
spawn('C:/a/b/c.exe', ['-n 100'], {
windowsVerbatimArguments: true
})
spawn('C:/a/b/c.exe', ['-n 100', '-t'])
其他问题
spawn的stdout输出的字符串乱码(���� Ping 127.0.0.1 ���� 32 �ֽڵ�����:)怎么解决?
https://www.npmjs.com/package/iconv-lite ,安装这个库,将其转为GBK编码进行输出即可。
ls.stdout.on('data', (data) => {
console.log(`stdout: ${iconv.decode(data, 'gbk')}`);
});
标签:spawn,shell,nodejs,process,Windows,进程,data From: https://www.cnblogs.com/XingXiaoMeng/p/18340325如果你想说为什么不使用Buffer.toString进行转换编码呢?那是因为Buffer支持的字符编码有限,不支持GBK字符串编码的转换。
https://nodejs.org/dist/v18.20.4/docs/api/buffer.html