在node.js 守护进程中,怎么向spawn和exec产生的子进程的stdin输入东西

nodejs调用脚本(python/shell)和系统命令 - 推酷
nodejs调用脚本(python/shell)和系统命令
每种语言都有自己的优势,互相结合起来各取所长程序执行起来效率更高或者说哪种实现方式较简单就用哪个,nodejs是利用子进程来调用系统命令或者文件,文档见
,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,代码如下:
var spawn = require('child_process').
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:
var exec = require('child_process').
var cmdStr = 'curl .cn/data/sk/.html';
exec(cmdStr, function(err,stdout,stderr){
console.log('get weather api error:'+stderr);
这个stdout的内容就是上面我curl出来的这个东西:
{&weatherinfo&:{&city&:&北京&,&cityid&:&&,&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:
PASSWORD=&&
NEWPASSWORD=&&
while getopts &H:U:P:N:& arg #选项后面的冒号表示该选项需要参数
case $arg in
IP=$OPTARG
NAME=$OPTARG
PASSWORD=$OPTARG
NEWPASSWORD=$OPTARG
#当有不认识的选项的时候arg为?
echo &含有未知参数&
#先获取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:
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传参数的简单说明一下:
# -*-coding:utf-8 -*-
需要模块:sys
参数个数:len(sys.argv)
sys.argv[0]
sys.argv[1]
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:
已发表评论数()
&&登&&&录&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
注* 此文是对其中命令行注入的详解
在这篇文章中,我们将学习正确使用Node.js调用系统命令的方法,以避免常见的命令行注入漏洞。
我们经常使用的调用命令的方法是最简单的child_process.exec。它有很一个简单的使用模式;通过传入一段字符串命令,并把一个错误或命令处理结果回传至回调函数中。
这里是你通过child_process.exec调用系统命令一个非常典型的例子。
child_process.exec('ls', function (err, data) {
console.log(data);});
不过,当你需要在你调用的命令中添加一些用户输入的参数时,会发生什么?显而易见的解决方案是把用户输入直接和您的命令进行字符串合并。但是,我多年的经验告诉我:当你将连接的字符串从一个系统发送到另一个系统时,总有一天会出问题。
var path = &user input&;child_process.exec('ls -l ' + path, function (err, data) {
console.log(data);});
为什么连接字符串会出问题?
嗯,因为在child_process.exec引擎下,将调用执行&/bin/sh&。而不是目标程序。已发送的命令只是被传递给一个新的&/bin/ sh'进程来执行shell。 child_process.exec的名字有一定误导性 - 这是一个bash的解释器,而不是启动一个程序。这意味着,所有的shell字符可能会产生毁灭性的后果,如果直接执行用户输入的参数。
[pid 25170] execve(&/bin/sh&, [&/bin/sh&, &-c&, &ls -l user input&], [/* 16 vars */]
比如,攻击者可以使用一个分号&;&来结束命令,并开始一个新的调用,他们可以使用反引号或$()来运行子命令。还有很多潜在的滥用。
那么什么是正确的调用方式?
execFile / spawn
像spawn和execFile采用一个额外的数组参数,不是一个shell环境下可以执行其他命令的参数,并不会运行额外的命令。
让我们使用的execFile和spawn修改一下之前的例子,看看系统调用有何不同,以及为什么它不容易受到命令注入。
child_process.execFile
var child_process = require('child_process');
var path = &.&child_process.execFile('/bin/ls', ['-l', path], function (err, result) {
console.log(result)});
运行的系统调用
[pid 25565] execve(&/bin/ls&, [&/bin/ls&, &-l&, &.&], [/* 16 vars */]
child_process.spawn
使用 spawn 替换的例子很相似。
var child_process = require('child_process');var path = &.&var ls = child_process.spawn('/bin/ls', ['-l', path])ls.stdout.on('data', function (data) {console.log(data.toString());});
运行的系统调用
[pid 26883] execve(&/bin/ls&, [&/bin/ls&, &-l&, &.&], [/* 16 vars */
当使用spawn或execfile时,我们的目标是只执行一个命令(参数)。这意味着用户不能运行注入的命令,因为/bin/ls并不知道如何处理反引号或pipe或;。它的/bin/bash将要解释的是那些命令的参数。它类似于使用将参数传入SQL查询(parameter),如果你熟悉的话。
但还需要警告的是:使用spawn或execFile并不总是安全的。例如,运行 /bin/find,并传入用户输入参数仍有可能导致系统被攻陷。 find命令有一些选项,允许读/写任意文件。
所以,这里有一些关于Node.js运行系统命令的指导建议:
避免使用child_process.exec,当需要包含用户输入的参数时更是如此,请牢记。
尽量避免让用户传入参数,使用选择项比让用户直接输入字符串要好得多。
如果你必须允许用户输入参数,请广泛参考该命令的参数,确定哪些选项是安全的,并建立一个白名单。
& 相关主题:利用NodeJS的子进程(child_process)调用系统命令的方法分享
利用NodeJS的子进程(child_process)调用系统命令的方法分享
NodeJS子进程简介 NodeJS子进程提供了与系统交互的重要接口,其主要API有: 标准输入、标准输出及标准错误输出的接口。 NodeJS子进程简介 NodeJS 子进程提供了与系统交互的重要接口,其主要 API 有: 标准输入、标准输出及标准错误输出的接口 child.stdin 获取标准输入 child.stdout 获取标准输出 child.stderr 获取标准错误输出 获取子进程的PID:child.pid 提供生成子进程的重要方法:child_process.spawn(cmd, args=[], [options]) 提供直接执行系统命令的重要方法:child_process.exec(cmd, [options], callback) 提供杀死进程的方法:child.kill(signal='SIGTERM') 实例一:利用子进程获取系统内存使用情况 将以下代码保存为 free.js:   复制代码 代码如下:  var spawn = require('child_process').spawn, free = spawn('free', ['-m']); // 捕获标准输出并将其打印到控制台 free.stdout.on('data', function (data) { console.log('标准输出:\n' + data); }); // 捕获标准错误输出并将其打印到控制台 free.stderr.on('data', function (data) { console.log('标准错误输出:\n' + data); }); // 注册子进程关闭事件 free.on('exit', function (code, signal) { console.log('子进程已退出,代码:' + code); });
执行代码后的结果: $ node free.js 标准输出: total used free shared buffers cached Mem: 74 0 135 959 -/+ buffers/cache: 879 3070 Swap: 5 子进程已退出,代码:0 以上输出相当与在命令行执行:free -m 命令。 通过这个简单的例子我们已经对子进程的使用有所了解,下面再来一个示例,用于演示exec 的使用方法。 实例二:利用子进程统计系统登录次数 将下面代码保存为 last.js   复制代码 代码如下:  var exec = require('child_process').exec, last = exec('last | wc -l'); last.stdout.on('data', function (data) { console.log('标准输出:' + data); }); last.on('exit', function (code) { console.log('子进程已关闭,代码:' + code); });
执行代码: $ node last.js 标准输出:203 子进程已关闭,代码:0 其与直接在命令行输入:last | wc -l 的结果是一样的。
&&&主编推荐
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
港口与航道工程建设工程法规及相关知识建设工程经济考试大纲矿业工程市政公用工程通信与广电工程
操作系统汇编语言计算机系统结构人工智能数据库系统微机与接口
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
Powerpoint教程WPS教程
电子政务客户关系管理首席信息官办公自动化大数据
职称考试题目
就业指导签约违约职业测评
招生信息考研政治
网络安全安全设置工具使用手机安全
3DMax教程Flash教程CorelDraw教程Director教程
Dreamwaver教程HTML教程网站策划网站运营Frontpage教程
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
互联网电信IT业界IT生活
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
组织运营财务资本
视频播放文件压缩杀毒软件输入法微博
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-}

我要回帖

更多关于 node.js 进程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信