首页 > 系统相关 >nodejs使用child_process模块启动(exec和spawn)子线程任务,子进程实例的kill()方法无效的问题

nodejs使用child_process模块启动(exec和spawn)子线程任务,子进程实例的kill()方法无效的问题

时间:2024-08-03 13:06:12浏览次数:9  
标签:spawn shell nodejs process Windows 进程 data

以下内容在win10环境下的执行分析(这里就不对进程和线程做区分了):

  1. child_process.execchild_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')}`);
});

如果你想说为什么不使用Buffer.toString进行转换编码呢?那是因为Buffer支持的字符编码有限,不支持GBK字符串编码的转换。
https://nodejs.org/dist/v18.20.4/docs/api/buffer.html

标签:spawn,shell,nodejs,process,Windows,进程,data
From: https://www.cnblogs.com/XingXiaoMeng/p/18340325

相关文章

  • Java9 Process API
    在负责控制和管理操作系统进程的Java9ProcessAPI中已经有了相当大的改进。ProcessHandle类提供进程本机进程ID,开始时间,累计CPU时间,参数,命令,用户,父进程和子进程。ProcessHandle类还提供了检查进程活性并销毁进程的方法。它具有onExit方法,当进程退出时,CompletableFuture类......
  • QT QProcess: Destroyed while process (“apple.exe“) is still running
    一、出错原因因为我这个程序是一直运行的,它会一直回显数据,如果你使用对象,start启动这个命令后,程序认为QProcess已经执行完毕,自动回收,但是此时程序正在执行中,所以无法销毁这个进程,导致出现这个问题。二、错误代码QStringcmd="./bin/apple.exe";QStringListargs;......
  • Qt之QProcess
    一、简介QProcess是Qt框架提供的一个类,用于在应用程序中执行外部进程。它提供了一系列函数来启动、控制和与外部进程进行交互。QProcess的一些重要特性和功能包括:启动外部进程:QProcess可以用于启动外部应用程序或命令行工具。通过start函数可以指定要执行的程序路径以及相关......
  • nodejs 使用 sequelize 实现 mysql数据库的批量插入
    直接上代码:/***设置mysql连接,返回连接实例。连接格式:账户:密码@数据库地址/具体数据库名称***/constsetConnect=()=>{constsequelize=newSequelize(`mysql://${你的mysql地址}`,{logging:(...msg)=>Logger.INSTANCE.inf......
  • GitHub Actions 工作流程中的 moviepy 安装错误:subprocess-exited-with-error
    我尝试在GitHubActions工作流程中安装moviepy时遇到错误。在我的本地机器上安装工作正常,但在CI环境中有时会失败。该错误消息表明获取构建轮子的要求未成功运行,退出代码为1。它还提到该错误源自子进程,并且可能不是pip的问题。Downloadingmoviepy-1.0.3.tar.gz(388......
  • ctfshow-web入门-nodejs系列
    web334下载源码后缀改为zip打开即可先对源码经行一个简单的分析login.js//引入Express框架varexpress=require('express');//创建一个路由实例varrouter=express.Router();//引入用户数据,假设user模块导出的是一个包含用户项的对象varusers=require('../m......
  • 微信小程序nodejs+vue+uniapp学生选课系统dmkas源码lw包安装
    系统分为学生和管理员,教师三个角色小程序端运行软件 微信开发者工具/hbuiderxuni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。基于微信小程序学生选课系统后台是本系统分为学生,教师,管理员三个角色,学生的主要功能是查看课程介......
  • Flink的DateStream API中的ProcessWindowFunction和AllWindowFunction两种用于窗口处
    目录ProcessWindowFunctionAllWindowFunction具体区别ProcessWindowFunction示例AllWindowFunction示例获取时间不同,一个数据产生的时间一个是数据处理的时间ProcessWindowFunctionAllWindowFunction具体示例ProcessWindowFunction示例AllWindowFunction示例总......
  • BeanPostProcessor 接口和@PostConstruct 在使用姿势上差异
    先说结论接口BeanPostProcessor更灵活,可以实现bean生命周期里前,后分别执行某些内容,必须是spring管理的bean才能实现此功能,不加@Component不生效@ComponentpublicclassMyBeanPostProcessorimplementsBeanPostProcessor{@OverridepublicObjectpostProcessBe......
  • Pentester Academy -Windows API Exploitation Recipes: Processes, Tokens and Memor
    早年为PentesterAcademy(https://www.pentesteracademy.com/),如今为INE(https://ine.com/)002安装VS社区版https://visualstudio.microsoft.com/zh-hans/003processlistingapi正在运行的是什么:服务,AV,HIDS/IPS等其他attack开始的点:进程注入,内存dump/修改,TokenSt......