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