js执⾏shell命令的⼏种⽅式(Node)
在做⼀个客户端基建项⽬的时候,多处需要⽤到JS调取命令⾏执⾏shell脚本,这⾥对shell命令、JS执⾏shell命令做⼀个简单的介绍和总结。
前⾔
⼀般在纯前端静态页⾯的项⽬中,是不需要JS调命令⾏操作的,通常在Node项⽬,或者在Electron客户端项⽬中,可能会有这样的需求。(electron这个客户端框架本⾝就内置了node的很多⽅法)。因此下⽂针对的是有node层的项⽬如何执⾏shell。
先来了解⼀下shell是什么?
Linux/Unix中的shell,翻译是’壳’的意思;shell提供了⽤户与内核进⾏交互操作的⼀种接⼝。它接收⽤户输⼊的命令并把它送⼊操作系统的内核去执⾏。
1、命令⾏
⽤户直接在shell界⾯上执⾏shell命令,⼀⾏⾏书写,很少写出成套的程序来执⾏,所以称为命令⾏。
2、shell脚本
⽤户事先编写⼀个sh脚本⽂件,⽽后使⽤shell程序执⾏该脚本,这种⽅式,我们称shell编程。
调起shell的⼏种⽅式介绍(不限于这⼏种)
1. child_process:node的⼀个⼦进程api,可创建⼀个⼦进程⽤于执⾏命令⾏
2. shelljs: 基于node的api封装的⼀个shell执⾏插件
3. simple-git :基于node的ap封装的⼀个git命令执⾏插件
依次来了解⼀下吧
1、child_process
介绍
child_process是node提供的⼀个⼦进程AP,具体可见、关于此类api的介绍,对衍⽣shell及参数有⾮常详细的说明,下⾯列出两个常⽤的api
1. (command[, options][, callback])
command:要运⾏的shell命令
创建⼀个新的shell进程,然后执⾏command
2. File(file[, args][, options][, callback])
file:要运⾏的⽂件名称或路径,参数作为数组传⼊
直接将可执⾏的file创建为新进程;需要单独写.sh⽂件,可编写复杂逻辑,但在windows上使⽤时会有兼容问题(此外,还有
child_process.spawn()等可供选择)
⽰例
const util =require('util');
const child_process =require(‘child_process');
// 调⽤util.promisify⽅法,返回⼀个promise,如const { stdout, stderr } = await exec('rm -rf build')
const exec = util.promisify();
const appPath =join(__dirname,'app');
const runClean =async function(){
// cwd指定⼦进程的当前⼯作⽬录这⾥的rm -rf build为删除指定⽬录下的⼀个⽂件夹
await exec(`rm -rf build`,{ cwd: appPath });
await exec(`rm -rf test`,{ cwd: appPath });
runClean();
2、shelljs
介绍
shelljs是j基于nodeAPI的⼀个扩展,要引⼊插件:();它⽐原⽣的child_process的兼容性更好,使⽤更灵活,这个插件的使⽤率很⾼。
Tips:
这个插件不仅可以调⽤.exec执⾏shell命令,也封装了⼀些快捷操作指令,具体使⽤⽂档请参考。
1. cat 返回⽂件内容
Const mdres = shell.cat(‘*.md’)
2. pwd 获取当前⽬录
const res = shell.pwd();
3. find 查⽂件
find(‘src’, ‘lib’);
find([‘src’, ‘lib’]); // same as above
find(’.’).filter(function(file) { return file.match(/.js$/); });
4. mkdir创建⽬录
mkdir(’-p’, ‘/tmp/a/b/c/d’, ‘/tmp/e/f/g’);
mkdir(’-p’, [’/tmp/a/b/c/d’, ‘/tmp/e/f/g’]); // same as above
⽰例
git常用指令
const shell =require(‘shelljs’);
……
<('/update-git',function(req, res, next){
// 如果⽬录存在,执⾏Git pull操作,否则新建⽬录,执⾏git clone 操作
istsSync(`${root}/${groupName}/${name}`)){
<('git pull',{
cwd:`${root}/${groupName}/${name}`,
});
}else{
<(`git clone ${remote}${name}`,{
cwd:`${root}/${groupName}`,
});
}
……
});
3、simple-git
鉴于上个例⼦,执⾏shell脚本操作git,其实对于复杂的git命令语句,写起来还是很不⽅便,最后介绍⼀个专为git设计的插件:simple-git()
介绍
1. 在项⽬中引⼊插件后,调⽤simple-git/promise可执⾏异步git操作,⽅便结合async/await使⽤
2. 它封装并⽀持了很多git的⽅法,⽐如clone、commit、status、pull等等,将cmd命令和参数,传⼊即可
3. 甚⾄可以⽤git.raw(),解析前端输⼊的git命令
⽰例
以下为客户端项⽬通过ipc通信,处理git的请求
const simpleGit =require('simple-git/promise');
......
// 执⾏客户端模拟的 simple-git 函数
ipcMain.handle('simple-git',async function(e,{ projectPath, cmd, args }){
const git =simpleGit(projectPath);
try{
const res =await git[cmd](...args);
return res;
}catch(e){
<('执⾏ simple-git 命令时发⽣错误',{ projectPath, cmd, args }, e);
throw e;
}
});
总结
上⾯介绍了shell的概念及三种js执⾏shell命令的⽅式(这⾥只列出了简单的命令,实际也可以根据需要编写.sh⽂件,传参相对路径,执⾏更复杂的shell脚本);总的来说,有以下⼏点:
1. shell是⼀种⽤户与内核进⾏交互操作的接⼝,我们通过执⾏shell命令⾏或者脚本可对本机⽂件、进程等进⾏操作。
2. js要执⾏shell命令,有很多⽅式,这⾥总结了⼏种基于node的⽅式:
1. child_process 原⽣nodeAPI,需根据需要选型
2. shelljs Node的⼀个扩展插件、兼容性好
3. simple-git
专为git命令打造的插件,轻量好⽤

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。