js执行shell命令的几种方式(Node)

作者:溜溜的阿溜 时间:2024-04-16 10:35:14 

在做一个客户端基建项目的时候,多处需要用到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的几种方式介绍(不限于这几种)

  • child_process:node的一个子进程api,可创建一个子进程用于执行命令行

  • shelljs: 基于node的api封装的一个shell执行插件

  • simple-git :基于node的ap封装的一个git命令执行插件

依次来了解一下吧

1、child_process

介绍

child_process是node提供的一个子进程AP,具体可见官网、中文网关于此类api的介绍,对衍生shell及参数有非常详细的说明,下面列出两个常用的api

1. child_process.exec(command[, options][, callback])
command:要运行的shell命令
创建一个新的shell进程,然后执行command

2. child_process.execFile(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(child_process.exec);
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的一个扩展,要引入插件:(npm地址);它比原生的child_process的兼容性更好,使用更灵活,这个插件的使用率很高。

Tips:
这个插件不仅可以调用.exec执行shell命令,也封装了一些快捷操作指令,具体使用文档请参考github地址。

cat 返回文件内容

Const mdres = shell.cat(‘*.md')

pwd 获取当前目录

const res = shell.pwd();

find 查找文件

find(‘src', ‘lib');
find([‘src', ‘lib']); // same as above
find('.').filter(function(file) { return file.match(/.js$/); });

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

示例

const shell = require(‘shelljs');
……
router.get('/update-git', function (req, res, next) {
  // 如果目录存在,执行Git pull操作,否则新建目录,执行git clone 操作
  if (fs.existsSync(`${root}/${groupName}/${name}`)) {
    shell.exec('git pull', {
      cwd: `${root}/${groupName}/${name}`,
    });
  } else {
    shell.exec(`git clone ${remote} ${name}`, {
      cwd: `${root}/${groupName}`,
    });
  }
……
});

3、simple-git

鉴于上个例子,执行shell脚本操作git,其实对于复杂的git命令语句,写起来还是很不方便,最后介绍一个专为git设计的插件:simple-git(npm地址)

介绍

  • 在项目中引入插件后,调用simple-git/promise可执行异步git操作,方便结合async/await使用

  • 它封装并支持了很多git的方法,比如clone、commit、status、pull等等,将cmd命令和参数,传入即可

  • 甚至可以用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) {
    console.error('执行 simple-git 命令时发生错误', { projectPath, cmd, args }, e);
    throw e;
  }
});
  • shell是一种用户与内核进行交互操作的接口,我们通过执行shell命令行或者脚本可对本机文件、进程等进行操作。

  • js要执行shell命令,有很多方式,这里总结了几种基于node的方式:

    • child_process 原生nodeAPI,需根据需要选型

    • shelljs Node的一个扩展插件、兼容性好

    • simple-git:专为git命令打造的插件,轻量好用

来源:https://blog.csdn.net/cindy647/article/details/108830841

标签:js,执行,shell
0
投稿

猜你喜欢

  • MySQL事务(transaction)看这篇就足够了

    2024-01-12 13:54:09
  • JavaScript中的对象的extensible属性介绍

    2024-06-05 09:30:38
  • 新手该如何学python怎么学好python?

    2022-06-20 07:33:27
  • 在漏洞利用Python代码真的很爽

    2023-11-24 15:57:29
  • 浅谈function(函数)中的动态参数

    2023-08-11 10:23:59
  • 使用tensorflow实现矩阵分解方式

    2022-04-17 17:01:17
  • pycharm通过anaconda安装pyqt5的教程

    2023-09-06 03:31:37
  • 微信小程序使用slider设置数据值及switch开关组件功能【附源码下载】

    2024-05-11 09:31:07
  • Pytest+Request+Allure+Jenkins实现接口自动化

    2021-04-09 13:50:44
  • windows下使用GoLand生成proto文件的方法步骤

    2023-08-25 16:04:21
  • MySql 5.7.17 winx64的安装配置详细教程

    2024-01-17 15:00:26
  • Python常用库Numpy进行矩阵运算详解

    2023-01-04 02:45:52
  • python感知机实现代码

    2022-03-12 14:59:50
  • Python之Pygame的Event事件模块

    2021-07-17 06:18:40
  • 如何使用Python的Requests包实现模拟登陆

    2022-10-07 03:12:26
  • Java实现从数据库导出大量数据记录并保存到文件的方法

    2024-01-16 09:47:37
  • MySQL利用索引优化ORDER BY排序语句的方法

    2024-01-24 00:19:34
  • python使用psutil模块获取系统状态

    2021-12-13 23:36:10
  • Vue不能watch数组和对象变化解决方案

    2024-04-30 10:41:06
  • 关于Youtube URL的十个技巧

    2009-04-21 13:19:00
  • asp之家 网络编程 m.aspxhome.com