nodejs调用脚本(python/shell)和系统命令
每种语言都有自己的优势,互相结合起来各取所长程序执行起来效率更高或者说哪种实现方式较简单就用哪个,nodejs是利用子进程来调用系统命令或者文件,文档见http://nodejs.org/api/child_process.html,NodeJS子进程提供了与系统交互的重要接口,其主要API有: 标准输入、标准输出及标准错误输出的接口。
NodeJS 子进程提供了与系统交互的重要接口,其主要 API 有:
标准输入、标准输出及标准错误输出的接口
child.stdin 获取标准输入
child.stdout 获取标准输出
child.stderr 获取标准错误输出
获取子进程的PID:child.pid
提供生成子进程的方法:child_process.spawn(cmd, args=[], [options])
提供直接执行系统命令的方法:child_process.exec(cmd, [options], callback)
提供调用脚本文件的方法:child_process.execFile(file, [args], [options], [callback])
提供杀死进程的方法:child.kill(signal='SIGTERM')
用实例来感受一下,很有意思的,呵呵~~
1、利用子进程调用系统命令(获取系统内存使用情况)
新建nodejs文件,名为cmd_spawn.js,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var spawn = require( 'child_process' ).spawn; free = spawn( 'free' , [ '-m' ]); / / 捕获标准输出并将其打印到控制台 free.stdout.on( 'data' , function (data) { console.log( 'standard output:\n' + data); }); / / 捕获标准错误输出并将其打印到控制台 free.stderr.on( 'data' , function (data) { console.log( 'standard error output:\n' + data); }); / / 注册子进程关闭事件 free.on( 'exit' , function (code, signal) { console.log( 'child process eixt ,exit:' + code); }); |
下面是运行该脚本和直接运行命令'free -m'的结果,一模一样:
2、执行系统命令(child_process.exec())
这个我还是很常用的,功能感觉比上面的强大那么一点点。比如我很喜欢关注天气,现在我要curl一下天气的接口返回json格式的数据,可能我要对它进行一番操作,这里就打印出来不操作。
新建nodejs文件,名为cmd_exec.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var exec = require( 'child_process' ). exec ; var cmdStr = 'curl http://www.weather.com.cn/data/sk/101010100.html' ; exec (cmdStr, function(err,stdout,stderr){ if (err) { console.log( 'get weather api error:' + stderr); } else { / * 这个stdout的内容就是上面我curl出来的这个东西: { "weatherinfo" :{ "city" : "北京" , "cityid" : "101010100" , "temp" : "3" , "WD" : "西北风" , "WS" : "3级" , "SD" : "23%" , "WSE" : "3" , "time" : "21:20" , "isRadar" : "1" , "Radar" : "JC_RADAR_AZ9010_JB" , "njd" : "暂无实况" , "qy" : "1019" }} * / var data = JSON.parse(stdout); console.log(data); } }); |
来感受一下直接curl出来和通过运行脚本的出来的结果是一样一样的:
3、调用传参数的shell脚本(child_process.execFile())
这个要先准备个shell脚本,比如我要连到一台服务器,来修改它的密码,则我要提供IP,user,new pwd,old pwd,新建shell脚本文件change_password.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/bin/sh IP = "" NAME = "" PASSWORD = "" NEWPASSWORD = "" while getopts "H:U:P:N:" arg #选项后面的冒号表示该选项需要参数 do case $arg in H) IP = $OPTARG ;; U) NAME = $OPTARG ;; P) PASSWORD = $OPTARG ;; N) NEWPASSWORD = $OPTARG ;; ?) #当有不认识的选项的时候arg为? echo "含有未知参数" exit 1 ;; esac done #先获取userid USERID = ` / usr / bin / ipmitool - I lanplus - H $IP - U $NAME - P $PASSWORD user list | grep root | awk '{print $1}' ` # echo $USERID #根据userid来修改密码 / usr / bin / ipmitool - I lanplus - H $IP - U $NAME - P $PASSWORD user set password $USERID $NEWPASSWORD |
然后我准备个nodejs文件来调用这个shell脚本,叫file_changepwd.js:
1 2 3 4 5 6 7 8 9 | var callfile = require( 'child_process' ); var ip = '1.1.1.1' ; var username = 'test' ; var password = 'pwd' ; var newpassword = 'newpwd' ; callfile. execFile ( 'change_password.sh' ,[ '-H' , ip, '-U' , username, '-P' , password, '-N' , newpassword],null,function (err, stdout, stderr) { callback(err, stdout, stderr); }); |
这里就不方便贴运行结果了,不过我可以用人格保证,它是经过测试的。
看过上面的,其实调用python脚本就没什么悬念了,本质上也就是执行命令。
4、调用python脚本(python脚本本身是传参数的)
这里插入一个题外话,下面这段是对python传参数的简单说明一下
1 2 3 4 5 6 7 8 9 10 11 12 | # -*-coding:utf-8 -*- ''' 需要模块:sys 参数个数:len(sys.argv) 脚本名: sys.argv[0] 参数1: sys.argv[1] 参数2: sys.argv[2] ''' import sys print u "脚本名:" , sys.argv[ 0 ] for i in range ( 1 , len (sys.argv)): #这里参数从1开始 print u "参数" , i, sys.argv[i] |
运行结果:
我也来准备一个nodejs文件来调用这个python脚本(我对py_test.py做了修改,见下面),file_python.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var exec = require( 'child_process' ). exec ; var arg1 = 'hello' var arg2 = 'jzhou' exec ( 'python py_test.py ' + arg1 + ' ' + arg2 + ' ' ,function(error,stdout,stderr){ if (stdout.length > 1 ){ console.log( 'you offer args:' ,stdout); } else { console.log( 'you don\'t offer args' ); } if (error) { console.info( 'stderr : ' + stderr); } }); py_test.py内容如下: # -*-coding:utf-8 -*- import sys print sys.argv |
运行结果如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?