使用javascript写shell脚本 二

5,704 阅读2分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

上篇文章总结了javascript写shell脚本的基础操作

这篇文章继续介绍执行如何linux命令行

执行linux命令行

原生方式child_process

nodejs可以使用child_process模块新建子进程,用来执行unit系统命令,写个测试的例子,如下所示:

#!/usr/bin/env node


//-----同步写法👇
const execSync=require('child_process').execSync

const res=execSync('ls')
console.log("res", res.toString())


// ----- 异步写法👇
const exec=require('child_process').exec
exec('ls',(err,stdout,stderr)=>{
   if(err)throw err
   console.log(stdout)
})

原生写法有些时候不太方便,所以在日常工作中一般会使用shelljs来代替child_process。

shelljs执行linux命令行

首先需要安装shelljs

npm i shelljs -S

shelljs提供了很多方法,最常用的是exec,举个栗子

const shell=require('shelljs')


/**
 * 函数签名:exec(command [, options] [, callback])
 * command:要执行的命令
 * callback:回调函数,对command的输出进行处理
 * options:
 *  async: 异步执行.如果callback提供了,会忽略该参数并强制异步执行  (default: false)
 *  fatal: Exit upon error (default: false).
 *  silent: 不在console中输出(default: false).
 *  encoding: 设置stdout和stderr的编码 (default: 'utf8')
 */

//输出ls的结果
shell.exec("ls")

//callback(code,stdout,stderr)  code为0则成功,否则失败
shell.exec("dir",{silent:true},(code,stdout,stderr)=>{})

shell.exec('ls',{silent:true},(code,stdout,stderr)=>{
    console.log(code)
    console.log(stdout)
})

例子-批量文件重命名

继续上一节的例子,我们来进行一些文件批量重命名操作

我有个test文件夹,文件如下,我要把所有的文件中的aabb去掉

test
├── 1aabb.html
├── 1aabb.txt
└── files
    ├── 2aabb.html
    └── 2aabb.jpg

业务逻辑:

  1. 递归读取所有文件夹
  2. 重命名文件

代码如下:

#!/usr/bin/env node

const fs = require('fs');
const path=require('path')

const shell=require('shelljs')
//递归读取文件
function walkSync(currentDirPath, callback) {
    fs.readdirSync(currentDirPath).forEach(function (name) {
        var filePath = path.join(currentDirPath, name);
        var stat = fs.statSync(filePath);
        if (stat.isFile()) {
            callback(filePath, stat);
        } else if (stat.isDirectory()) {
            walkSync(filePath, callback);
        }
    });
}
// 获取新的路径,里面写的是重命名的逻辑,可以根据实际需要更改
function getNewPath(path){
    const tmp=path.split('/')
    const fileName=tmp.pop()
    newFileName=fileName.replace('aabb','')
    return tmp.join('/')+'/'+newFileName
}
//------------- 业务逻辑:
;(function(){
    const [nodeEnv,dir,...args]=process.argv
    // 获取用户输入的路径
    const folder=args[0]
    if(!folder)throw Error('请提供文件夹路径!')
    walkSync(folder,(filePath,stat)=>{
        //重命名操作: 1aabb.html -> 1.html 即去除aabb
        shell.exec(`mv ${filePath} ${getNewPath(filePath)}`)
    })
}())

使用方式

 node shell/getFile /Users/h/self-apps/2020-practice/node/test

代码放在这里: 代码地址