## [shelljs](https://www.npmjs.com/package/shelljs)
`shelljs`模塊重新包裝了`child_process`,調用系統命令更加簡單。
`shelljs`是`Unix Shell`在`Node.js API`層的輕量級實現,可以支持`Windows、Linux、OS X`。你可以像在`Unix`命令行敲命令一樣書寫代碼
[TOC]
### shelljs的安裝
`shelljs`是第三方模塊,需要安裝后才能使用。
* 全局安裝
~~~
$ npm install shelljs -g
~~~
* 本地安裝
將當前工作目錄切換為需要使用`shelljs`模塊的目錄(已經創建了`package.json`文件的目錄)
~~~
$ npm install shelljs --save
~~~
### shelljs的使用說明
對于熟悉`Unix Shell`腳本的開發者,簡單掃一眼API就能愉快的開始寫代碼了。不熟悉的也沒關系,`shelljs`絕大部分命令都是對文件和文件夾的操作,我們在[文件系統處理](313189)一節已經詳細的將對文件系統處理相關的接口介紹了一遍,使用`fs-extra`模塊處理文件系統相關的操作會簡單很多,
先看個例子:
~~~
var shell = require('shelljs');
//判定git命令是否可用
if (!shell.which('git')) {
//向命令行打印git命令不可用的提示信息
shell.echo('Sorry, this script requires git');
//退出當前進程
shell.exit(1);
}
//先刪除'out/Release'目錄
shell.rm('-rf', 'out/Release');
//拷貝文件到'out/Release'目錄
shell.cp('-R', 'stuff/', 'out/Release');
//切換當前工作目錄到'lib'
shell.cd('lib');
//shell.ls('*.js')返回值是一個包含所有js文件路徑的數組
shell.ls('*.js').forEach(function(file) {//遍歷數組
//sed命令用于文件內容的替換,這里是對每個文件都執行如下3步操作,更改版本信息
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('..');
//同步執行git命令提交代碼
if (shell.exec('git commit -am "Auto-commit"').code !== 0) {
shell.echo('Error: Git commit failed');
shell.exit(1);
}
~~~
上面的例子展示了一個可發布版本提交到`git`倉庫的過程。
`shelljs`的方法都遵循:
**方法名就是我們常用的執行命令,而方法參數就是命令行參數。只是有些方法對命令行參數做了變形和拓展。**
### 重要方法介紹
#### exec()
* exec(command [, options] [, callback])
* `command <String>`:要在命令行執行的完整命令
* `options <Object>`:可選參數,JSON對象
* async: 異步執行.如果你提供了回調方法,這個值就一定為true,無論你怎么設置
* silent:打印信息不輸出到命令控制臺
* Node.js 的 [child_process.exec()](http://nodejs.cn/api/child_process.html#child_process_child_process_exec_command_options_callback)方法的其他參數都可以用
* ` callback:<Function>`:當進程終止時調用,并帶上輸出。
* `error <Error>`
* `stdout <String> | <Buffer>`
* `stderr <String> | <Buffer>`
* 返回值: 同步模式下,將返回一個ShellString(shelljs v0.6.xf返回一個形如{ code:..., stdout:... , stderr:... }的對象);異步模式下,將返回一個child_process的對象
>Note:
由于`exec()`現在同步方法的實現占用了大量`CPU`,所以,官方建議使用**異步模式**運行一個需要長時間保活的進程。
例子:
~~~
var version = exec('node --version', {silent:true}).stdout;
var child = exec('some_long_running_process', {async:true});
child.stdout.on('data', function(data) {
/* ... do something with data ... */
});
exec('some_long_running_process', function(code, stdout, stderr) {
console.log('Exit code:', code);
console.log('Program output:', stdout);
console.log('Program stderr:', stderr);
});
~~~
#### ls()
* `ls([options,] path_array)`
* `options <String>`:可選參數,可以多個參數疊加使用,比如-lA
* `-R`: 遞歸處理,將指定目錄下的所有文件及子目錄一并處理
* `-A`: 顯示除影藏文件“.”和“..”以外的所有文件列表
* `-L`: 如果遇到性質為符號鏈接的文件或目錄,直接列出該鏈接所指向的原始文件或目錄
* `-d`: 僅顯示目錄名,而不顯示目錄下的內容列表。顯示符號鏈接文件本身,而不顯示其所指向的目錄列表
* `-l`: 以長格式顯示目錄下的內容列表。輸出的信息從左到右依次包括文件名,文件類型、權限模式、硬連接數、所有者、組、文件大小和文件的最后修改時間等
* `path_array <Array>`:可選參數,目標目錄的組成的數組,ls命令依次處理各個目錄
* `ls([options,] [path, ...])`
* `options <String>`:可選參數,與`ls([options,] path_array)`方法的參數一樣
* ` [path, ...]`:可選參數,目標目錄序列,以多參數的形式存在,
比如:ls ( path1, path2 , ... , pathN);
**ls方法返回一個包含給定的目標目錄下的所有文件或目錄路徑集合的數組,如果沒有給定路徑,則默認為當前路徑。如果設置了上面的提到的參數,則按照給定參數逐條將結果保存在數組中。**
例子:
~~~
ls('projs/*.js');//
ls('-R', '/users/me', '/tmp');//遞歸遍歷'/users/me'和'/tmp'
ls('-R', ['/users/me', '/tmp']); // 和上面一條一樣
ls('-l', 'file.txt'); //[ { name: 'file.txt', mode: 33188, nlink: 1, ...} ]
~~~
#### ShellString()
* ShellString(str)
* `str <String>`:常規字符串
`ShellString()`方法用于將常規字符串轉換為`ShellString`。這樣,就可以使用`ShellString`的方法`to()`和`toEnd()`。
#### ShellString.prototype.to(file)
**類似`Unix`命令中的*重定向操作>*,即把`ShellString`的內容覆蓋寫入參數指定的`file`。**
例子:
~~~
//將input.txt的內容寫入outpu.txt
cat('input.txt').to('output.txt');
~~~
#### ShellString.prototype.toEnd(file)
**類似`Unix`命令中的*重定向并附加操作>>*,即把`ShellString`的內容寫到指定文件的末尾。**
例子:
~~~
//將input.txt的內容附加outpu.txt的末尾
cat('input.txt').to('output.txt');
~~~
### shelljs API地址
**`shelljs`官網地址:https://www.npmjs.com/package/shelljs**