社区电脑网络 → 浏览:帖子主题
* 帖子主题:shelljs
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 1 楼 ] 回复
shelljs模块重新包装了child_process,调用系统命令更加简单。
shelljs是Unix Shell在Node.js API层的轻量级实现,可以支持Windows、Linux、OS X。你可以像在Unix命令行敲命令一样书写代码。

shelljs安装
shelljs使用说明
方法介绍
exec()
ls()
ShellString()
ShellString.prototype.to(file)
ShellString.prototype.toEnd(file)
shelljs API地址

shelljs是第三方模块,需要安装后才能使用。

全局安装
$ npm install shelljs -g

本地安装
将当前工作目录切换为需要使用shelljs模块的目录(已经创建了package.json文件的目录)。
$ npm install shelljs --save

shelljs使用说明

对于熟悉Unix Shell脚本的开发者,简单扫一眼API就能愉快的开始写代码了。不熟悉的也没关系,shelljs绝大部分命令都是对文件和文件夹的操作,我们在文件系统处理一节已经详细的将对文件系统处理相关的接口介绍了一遍,使用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()方法的其他参数都可以用
        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, ...} ]

2023-01-01 13:12:42 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 2 楼 ] 回复
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').toEnd('output.txt');

shelljs官网地址:https://www.npmjs.com/package/shelljs
2023-01-01 13:12:50 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 3 楼 ] 回复
// 局部模式
const shell = require('shelljs');
const fs = require('fs');
const files = fs.readdirSync('../packages/components').filter(name => !["theme-default", "index.ts", "types.ts","package.json","version.ts","Base"].includes(name));

// 解压的webhook
// const originUzipUrl = 'http://172.17.0.10:31000/ssh?projectName=fdj_test';

if (shell.exec('yarn build:theme').code !== 0) {
    // 执行npm run build 命令
    shell.echo('Error: get coding failed')
    shell.exit(1)
}

if (shell.exec('yarn build:package').code !== 0) {
    // 执行npm run build 命令
    shell.echo('Error: build failed')
    shell.exit(1)
}

files.map(item=>{
    shell.cp(`../packages/components/${item}/README.md`,`../lib/${item}/README.md`)
})
2023-01-01 13:46:10 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 4 楼 ] 回复
//example
const shell = require('shelljs');

// 建立文件夹
shell.mkdir('./test');
// 进入文件夹
shell.cd('./test');
// 建立文件
shell.touch('hello.js');
// 执行命令,将命令写入文件
shell.exec( "echo console.log('hello world') >> hello.js");
// 执行文件,输出结果
shell.exec('node ../test/hello.js');

//output:hello world
2023-01-01 13:47:08 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 5 楼 ] 回复
基本语法

shell.which(command)
在环境变量PATH中寻找指定命令的地址,判断该命令是否可执行,返回该命令的绝对地址

echo
在控制台输出指定内容

exit(code)
以退出码为code退出当前进程
// 引入shelljs
var shell = require('shelljs')

//检查控制台是否以运行`git `开头的命令
if (!shell.which('git')) {
  //在控制台输出内容
  shell.echo('Sorry, this script requires git');
  shell.exit(1);
}

rm([options,] file [,file ...])
删除一个目录中一个或多个文件或目录,一旦删除,无法恢复。
常用参数:
-f:强制删除文件;
-i:删除之前先询问用户;
-r:递归处理目录;
-v:显示处理过程;
shell.rm('-rf','out/Release')  //强制递归删除`out/Release目录`

cp([options,] source_array, dest)
用来将一个或多个源文件或目录复制到指定的文件或目录
shell.cp('-R','stuff/','out/Release')  //将`stuff/`中所有内容拷贝至`out/Release`目录

cd
切换工作目录至指定的相对路径或绝对路径。cd..为返回上一级,cd-回到前一目录
shell.cd('lib')  //进入`lib`目录

ls
用来显示目标列表
ls(path.join('bundle', 'css/')).forEach(cssName => {
  ***
})

sed([options,] search_regex, replacement, file_array)
将file_array中符合search_regex的内容替换为replacement,支持正则的捕获组自引用。一次处理一行内容,处理完成后把缓冲区内容送往屏幕,然后处理下一行,循环直至结束。
/* -i表示直接作用源文件 */
/* 将build_version字段替换为'v0.1.2' */
shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', file);

cat([options,] file [, file ...])
将一个或多个文件内容读入,指定一个文件时读入该文件,指定多个文件时将内容连接在一起读入。
2023-01-01 14:14:49 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 6 楼 ] 回复
shelljs一些常用的命令行

    file相关
        cat
        cp
        find
        grep
        head
        ln
        ls
        mv
        rm
        sed
        sort
        tail
        ShellString.prototype.to(file)
        ShellString.prototype.toEnd(file)
        touch
    目录相关

file相关

整理一些关于文件(file)操作的常用命令,供自己查询使用。
cat

用法:返回包含给定文件的字符串,如果给定了多个文件,则返回包含文件的串联字符串。正向查看文件的内容。

    cat ( [options,] 文件 [, file.. .] )
    cat ( [options,] file_array )
    可用选项:
    -n: 输出所有行,标示文件的行数

例:

    var str =cat('file*.txt');
    var str =cat('file1', 'file2');
    var str =cat(['file1', 'file2']);

cp

用法: 复制文件。

    cp ( [options,] 源 [, source.. .],dest )
    cp ( [options,] source_array,dest )
    可用选项:
    -f: 强制( 默认行为)
    -n: 没有 clobber
    -u: 仅在源更新时复制
    -R: 递归
    -L: 跟随链接符号
    -P: 不跟踪符号符号

例:

    cp('file1', 'dir1');
    cp('-R', 'path/to/dir/', '~/newCopy/');
    cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
    cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as 上面

find

用法:顾名思义是查找文件的意思,返回给定路径中所有文件的array,find与ls(’-R’, path)的主要区别是find产生的文件名包括基目录,比如 src/lib/file1,而不仅仅是 file1。

    find( 路径 [, path.. .] )
    find( path_array )

例:

    find('src', 'lib');
    find(['src', 'lib']); // same as 上面
    find('.').filter(function(file) { returnfile.match(/.js$/); });

grep

用法:从给定文件读取输入字符串并返回包含给定文件的所有行的字符串。

    grep ( [options,] regex_filter,文件 [, file.. .] )
    grep( [options,],file_array )
    可用选项:
    -v: 反转 正规表达式的意义并打印与标准不匹配的行。
    -L: 只打印匹配文件的文件名

例:

    grep('-v', 'GLOBAL_VARIABLE', '*.js');
    grep('GLOBAL_VARIABLE', '*.js');

head

用法:读取文件的开头。

    head( [ {'-n': <num> },] 文件 [, file.. .]
    head( [ {'-n': <num> },] file_array
    可用选项:
    -n <num>: 显示文件的第一个 <num> 行

例:

    var str =head({'-n':1}, 'file*.txt');
    var str =head('file1', 'file2');
    var str =head(['file1', 'file2']); // same as 上面

ln

用法:创建一个指向文件或目录的物理链接 ,如果目标已经存在,使用-f强制链接。

    ( [options,] 源[source],dest )
    可用选项:
    -s: 链接符号
    -f: 强制

例:

    ln('file', 'newlink');
    ln('-sf', 'file', 'existing');

ls

用法:返回给定路径中的文件的array,如果未提供路径,则返回当前目录。

    ls ( [options,] [path,.. .] )
    ls ( [options,] path_array )
    可用选项:
    -R: 递归
    -A: 所有文件( 包括以 . 开头的文件,. 和 .. 除外)
    -L: 跟随链接符号
    -d: 列出目录本身,而不是它们的内容
    -L: 列出代表每个文件的对象,每个文件包含包含 ls -l 输出字段的字段

例:

    ls('projs/*.js');ls('-R', '/users/me', '/tmp');
    ls('-R', ['/users/me', '/tmp']); // same as 上面
    ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1,.. .}

mv

用法:移动文件。

    ( [options, ] 源 [, source.. .],目标')
    ( [options, ] source_array,目标')
    可用选项:
    -f: 强制( 默认行为)
    -n: 没有 clobber

例:

    mv('-n', 'file', 'dir/');
    mv('file1', 'file2', 'dir/');
    mv(['file1', 'file2'], 'dir/'); // same as 上面

rm

用法:删除文件。

    rm ( [options,] 文件 [, file.. .] )
    rm ( [options,] file_array )
    可用选项:
    -f: 强制
    -r: 递归

例:

    rm('-rf', '/tmp/*');
    rm('some_file.txt', 'another_file.txt');
    rm(['some_file.txt', 'another_file.txt']); // same as 上面

sed

用法:从 files 读取输入字符串,并使用给定的搜索 正规表达式 和替换字符串或者函数在输入上执行一个 JavaScript replace()。 替换后返回新字符串。

    sed ( [options,] search_regex,替换,文件 [, file.. .] )
    sed( [options,] search_regex,替换,file_array )
    可用选项:
    -i: 替换'文件'的内容。 注意,不会创建备份 !

例:

    sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
    sed(/.*DELETE_THIS_LINE.*n/, '', 'source.js');

sort

用法:返回文件的内容,排序为 line-by-line。 对多个文件进行排序与它们的内容混合,就像unix排序一样。

    sort( [options,] 文件 [, file.. .] )
    sort( [options,] file_array )
    可用选项:
    -R: 反转比较结果
    -n: 根据数值比较

例:

    sort('foo.txt', 'bar.txt');
    sort('-r', 'foo.txt');

tail

用法:读取文件的结尾。

    tail ({-n: <num> },] 文件 [, file.. .])
    tail ({-n: <num> },] file_array)
    可用选项:
    -n <num>: 显示文件的最后一个 <num> 行

例:

    var str =tail({'-n':1}, 'file*.txt');
    var str =tail('file1', 'file2');
    var str =tail(['file1', 'file2']); // same as 上面





2023-01-01 14:43:36 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 7 楼 ] 回复
ShellString.prototype.to(file)

用法:类似于Unix中的重定向运算符 >,但与 ShellStrings ( 如 cat。grep 等返回的) 一起工作。 Unix重定向一样,会覆盖任何现有文件 !

    cat(file).to(file);
    grep(file).to(file);

例:

    cat('input.txt').to('output.txt');

ShellString.prototype.toEnd(file)

用法:类似于Unix中的redirect-and-append操作符 >>,但它与 ShellStrings ( 如 cat。grep 等返回的)。

    cat(file).toEnd(file);
    grep(file).toEnd(file);

例:

    cat('input.txt').toEnd('output.txt');

touch

用法:将每个的访问及修改时间都更新为目前时间。除非是-c,否则会创建新的文件。

    touch( [options,] 文件 [, file.. .] )
    touch( [options,] file_array )
    可用选项:
    -A: 只更改访问时间
    -c: 不创建任何文件
    -m: 只更改修改时间
    -d DATE: 分析日期并使用它而不是当前时间
    -r FILE: 使用文件的时间代替当前时间

例:

    touch('source.js');
    touch('-c', '/path/to/some/dir/source.js');
    touch({ '-r':FILE }, '/path/to/some/dir/source.js');

2023-01-01 14:43:47 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 8 楼 ] 回复
chmod([options,] octal_mode || octal_string, file)
chmod([options,] symbolic_mode, file)

Available options:

    -v: output a diagnostic for every file processed
    -c: like verbose, but report only when a change is made
    -R: change files and directories recursively

Examples:

chmod(755, '/Users/brandon');
chmod('755', '/Users/brandon'); // same as above
chmod('u+x', '/Users/brandon');
chmod('-R', 'a-w', '/Users/brandon');


2023-01-01 14:56:09 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 9 楼 ] 回复
shell中的set、seq、eval、exec、&&和||
一、set

查看set 帮助:

bash -c "help set"

选项:

    -e:任何命令执行失败(非0 status)直接退出
    -x: 打印执行过程的命令行、参数
    +e:命令执行失败不会中断退出
    +x:不打印执行过程的命令行、参数

二、seq

seq: 打印数字序列

用法:seq first [incr] last

NAME
    seq -- print sequences of numbers

SYNOPSIS
    seq [-w] [-f format] [-s string] [-t string] [first [incr]] last

➜  blj seq 0 2
0
1
2

三、eval && exec

都是内建命令。

1.eval

    bashshell中内建的一个命令,命令后面所跟的内容都认为是参数,但是会两次扫描其参数:第一次扫描会将参数中的变量进行替换;第二次扫描会将后面的参数当作一个shell中的命令组合来执行命令。
    实际使用中,可以将任意组合的命令赋值给一个变量,然后在需要的位置通过 eval $variable 来执行这个命令。
    常见用法:
        直接组合命令 : eval ls -al
        替换变量
        可以执行任何值为命令组合的变量
        变量替换赋值

2.exec

    也是shell内建的一个命令。类似 eval、source,不同的是exec执行后面的命令会替换当前shell进程,而前两者不会。
    常见用法:
        用于分离执行脚本,并退出子脚本的shell进程
        用于设置描述符重定向输入文件内容
        用于设置描述符重定向输出内容至文件

四、&&和 ||

    command1 && command2 [&& command3 ...]
        左边的命令返回真后,右边的命令才能够被执行
        只要有一个命令返回假,后面的命令就不会被执行
    command1 || command2
        只有左边的命令返回假($? ==1),右边的命令才能被执行,即实现短路逻辑或操作。
        只要有一个命令返回真,后面的命令就不会被执行

2023-01-01 15:41:37 IP:已设置保密
pojin (ID: 1)
头衔:论坛坛主
等级:究级天王[荣誉]
积分:1301
发帖:99
来自:保密
注册:2022-08-28 23:20:57
造访:2025-03-23 21:18:24
[ 第 10 楼 ] 回复
command1 & command2 & command3    三个命令同时执行

command1; command2; command3          不管前面命令执行成功没有,后面的命令继续执行

command1 && command2                        只有前面命令执行成功,后面命令才继续执行
2023-01-02 00:44:40 IP:已设置保密
分页: 1, 共 1 页
快速回复主题
账号/密码
用户: 没有注册?密码:
评论内容