為什么使用 ShellJS
最近在做發版系統,需要在JS中執行 shell
,看了一些開源庫,發現大部分都是選用了 shelljs
,發現這個工具用起來太爽了,它的npm周下載量達到了 5,998,285
,這足以能證明它的強大之處, 遂記錄分享。
參考地址:https://www.npmjs.com/package/shelljs
快速體驗
shell.exec 方法使用
我們以查找 git
命令所在目錄為例:
const shell = require('shelljs');
const res = shell.exec('which scp');
console.log(res);
在這里,如果返回值的 code
屬性為 0
,則表示找到了這個命令,其路徑值存在屬性stdout
中。如果返回值為 1
表示沒有找到該命令。
shell.exec 方法類型
借助 VScode 可以找到 shell.exec
的類型:
export interface ExecFunction {
/**
* @desc 同步執行命令
* @param string 執行的命令
* @return 返回對象(包含code和output)
* code 為0表示操作正常, 為1表示操作異常
* output 實際的結果
*/
(command: string): ShellString;
/**
* @desc 同步執行命令
* @param string 執行的命令
* @param options 見 “理解 ShellJS 中的類型”
* @return 返回對象(包含code和output)
* code 為0表示操作正常, 為1表示操作異常
* output 實際的結果
*/
(command: string, options: ExecOptions & { async?: false }): ShellString;
/**
* 和上面差不多,但是時異步流程
*/
(
command: string,
options: ExecOptions & { async: true }
): child.ChildProcess;
/**
* 同步或者異步執行, 返回聯合類型
*/
(command: string, options: ExecOptions): ShellString | child.ChildProcess;
/**
* 異步執行
*/
(
command: string,
options: ExecOptions,
callback: ExecCallback
): child.ChildProcess;
/**
* 異步執行
*/
(command: string, callback: ExecCallback): child.ChildProcess;
}
ShellJS 注意點
關於文件名通配符
shelljs 所有命令都支持標准的 bash
文件名通配符,比如:
?
匹配一個任意字符。*
匹配0個一個或多個任意字符。[]
匹配中括號中任意一個字符。[-]
匹配中括號中任意一個字符,- 代表范圍。[^]
邏輯非,匹配不是中括號內的一個字符
同時 shelljs 兼容 node glob module
,詳見 https://github.com/isaacs/node-glob。
源碼 ExecOptions 接口
export interface ExecOptions extends child.ExecOptions {
/**
* Do not echo program output to the console.
* 不輸出output到控制台
* @default false
*/
silent?: boolean;
/**
* Exit when command return code is non-zero.
* 當狀態不為0時結束程序
* @default false
*/
fatal?: boolean;
/**
* Asynchronous execution.
* 是否異步執行
* If a callback is provided, it will be set to `true`, regardless of the passed value.
* 如果提供了回調函數,這個值會被設置為true,會忽略傳進來的值
* @default false
*/
async?: boolean;
/**
* Character encoding to use.
* 設置輸出的字符串編碼
* Affects the values returned by `stdout` and `stderr`,
* and what is written to `stdout` and `stderr` when not in silent mode
* @default "utf8"
*/
encoding?: string;
}
快捷方法
如果每次執行 shell 命令都需要寫 shelljs.exec(command)
,那么會讓你覺得很繁瑣,因此 shelljs 封裝了對應的快捷操作命令,而且命令的可選參數通常放在第一位:
// 查看是否安裝 git
if (!shell.which('git')) {
shell.echo('Sorry, this script requires git');
shell.exit(1);
}
// 文件復制
shell.rm('-rf', 'out/Release');
shell.cp('-R', 'stuff/', 'out/Release');
// 目錄切換
shell.cd('lib');
shell.ls('*.js').forEach(function (file) {
shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
shell.sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', file);
shell.sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, shell.cat('macro.js'), file);
});
shell.cd('..');
API 列表
cat
const shell = require('shelljs');
// 把所有md文件全部內容組合起來, 返回新的字符串
var str = shell.cat('*.md');
console.log(str)
// 返回 test2.md 文件的內容
var str = shell.cat('test2.md');
console.log(str)
// 顯示所有行號
var str = shell.cat("-n", 'test2.md');
console.log(str)
pwd
const shell = require('shelljs');
// 獲取當前目錄(執行命令的目錄)
// process.cwd() 會返回相同的結果
const res = shell.pwd();
console.log(res)
未完待續...