js執(zhí)行shell命令的幾種方式(Node)
在做一個客戶端基建項目的時候,多處需要用到JS調取命令行執(zhí)行shell腳本,這里對shell命令、JS執(zhí)行shell命令做一個簡單的介紹和總結。
前言
一般在純前端靜態(tài)頁面的項目中,是不需要JS調命令行操作的,通常在Node項目,或者在Electron客戶端項目中,可能會有這樣的需求。(electron這個客戶端框架本身就內置了node的很多方法)。因此下文針對的是有node層的項目如何執(zhí)行shell。
先來了解一下shell是什么?
Linux/Unix中的shell,翻譯是’殼’的意思;shell提供了用戶與內核進行交互操作的一種接口。它接收用戶輸入的命令并把它送入操作系統(tǒng)的內核去執(zhí)行。
1、命令行
用戶直接在shell界面上執(zhí)行shell命令,一行行書寫,很少寫出成套的程序來執(zhí)行,所以稱為命令行。
2、shell腳本
用戶事先編寫一個sh腳本文件,而后使用shell程序執(zhí)行該腳本,這種方式,我們稱shell編程。
調起shell的幾種方式介紹(不限于這幾種)
- child_process:node的一個子進程api,可創(chuàng)建一個子進程用于執(zhí)行命令行
- shelljs: 基于node的api封裝的一個shell執(zhí)行插件
- simple-git :基于node的ap封裝的一個git命令執(zhí)行插件
依次來了解一下吧
1、child_process
介紹
child_process是node提供的一個子進程AP,具體可見官網、中文網關于此類api的介紹,對衍生shell及參數(shù)有非常詳細的說明,下面列出兩個常用的api
1. child_process.exec(command[, options][, callback])
command:要運行的shell命令
創(chuàng)建一個新的shell進程,然后執(zhí)行command
2. child_process.execFile(file[, args][, options][, callback])
file:要運行的文件名稱或路徑,參數(shù)作為數(shù)組傳入
直接將可執(zhí)行的file創(chuàng)建為新進程;需要單獨寫.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執(zhí)行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創(chuàng)建目錄
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) { ? // 如果目錄存在,執(zhí)行Git pull操作,否則新建目錄,執(zhí)行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
鑒于上個例子,執(zhí)行shell腳本操作git,其實對于復雜的git命令語句,寫起來還是很不方便,最后介紹一個專為git設計的插件:simple-git(npm地址)
介紹
- 在項目中引入插件后,調用simple-git/promise可執(zhí)行異步git操作,方便結合async/await使用
- 它封裝并支持了很多git的方法,比如clone、commit、status、pull等等,將cmd命令和參數(shù),傳入即可
- 甚至可以用git.raw(),解析前端輸入的git命令
示例
以下為客戶端項目通過ipc通信,處理git的請求
const simpleGit = require('simple-git/promise'); ...... // 執(zhí)行客戶端模擬的 simple-git 函數(shù) 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('執(zhí)行 simple-git 命令時發(fā)生錯誤', { projectPath, cmd, args }, e); ? ? throw e; ? } });
總結
上面介紹了shell的概念及三種js執(zhí)行shell命令的方式(這里只列出了簡單的命令,實際也可以根據(jù)需要編寫.sh文件,傳參相對路徑,執(zhí)行更復雜的shell腳本);總的來說,有以下幾點:
- shell是一種用戶與內核進行交互操作的接口,我們通過執(zhí)行shell命令行或者腳本可對本機文件、進程等進行操作。
- js要執(zhí)行shell命令,有很多方式,這里總結了幾種基于node的方式:
- child_process 原生nodeAPI,需根據(jù)需要選型
- shelljs Node的一個擴展插件、兼容性好
- simple-git:專為git命令打造的插件,輕量好用
到此這篇關于js執(zhí)行shell命令的幾種方式(Node)的文章就介紹到這了,更多相關js執(zhí)行shell命令內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
webpack使用 babel-loader 轉換 ES6代碼示例
本篇文章主要介紹了webpack使用 babel-loader 轉換 ES6代碼 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-08-08window.open 以post方式傳遞參數(shù)示例代碼
這篇文章主要介紹了window.open以post方式傳遞參數(shù)的方法,需要的朋友可以參考下2014-02-02用 js 的 selection range 操作選擇區(qū)域內容和圖片
本篇文章主要介紹了用js的selection range操作選擇區(qū)域內容和圖片的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04js數(shù)字滑動時鐘的簡單實現(xiàn)(示例講解)
下面小編就為大家?guī)硪黄猨s數(shù)字滑動時鐘的簡單實現(xiàn)(示例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08