如何从Nodejs应用程序中执行shell脚本文件

3,228 阅读4分钟

有时,我们想从nodejs代码中执行shellbash 脚本文件,本教程讲述了如何在nodejs应用程序中从javascript代码和命令行运行shell脚本文件。

为什么我们需要从nodejs程序中运行shell脚本文件?

  • 通过在javascript程序中运行unix shell脚本,有助于实现服务器端任务的自动化。
  • 批量执行工作,以发送电子邮件或复制、删除或在文件系统之间同步文件。
  • 当你从javascript中执行操作系统相关的指令与文件系统进行交互时,它可以提高性能。

通过nodejs,Shell脚本的执行是通过接受输入和处理并从代码中发送输出。

在NodeJS应用程序中,我们可以通过多种方式从命令行执行Shell脚本。

  • 内置的child_process模块:你可以有一个shell或bash脚本文件,并使用child_process 模块从javascript代码执行。
  • ShellJS模块:在这种方法中,不需要脚本文件,相反,它从javascript中提供可移植的独立unix命令。

child_process模块允许你启动shell或bash窗口并在shell窗口执行脚本文件。

它为程序中的主nodejs进程提供新的子进程。

它提供了两个函数来执行nodejs应用程序的脚本文件。

子进程exec函数

exec函数创建一个新的shell,并在新的shell窗口中执行shell脚本文件。

执行的输出是缓冲的,可以用于nodejs的回调。

下面是一个语法

child_process.exec(command or script file,[, options][, callback]);


It has three parameters
- command or script file : can be unix commands or shell/bash script file
- options : are command line arguments can be passed
- callback : It is an function with `error`, `stdin` and `stdout` parameters are of type string or Buffer type in nodejs.


Here is an javascript code to remove an files from a folder
First import child_process module using require command
```javascript
var cp = require('child_process');

delete.js

const { exec } = require("child_process");

exec("rm -rf",["dist"] (error, stdout, stderr) => {
    if (error) {
        console.log('Error in removing files');
        return;
    }
    if (stderr) {
        console.log('an error with file system'');
        return;
    }
    console.log('Result of rm -rf command output',);
});

运行下面的命令会删除dist文件夹中的所有文件。

node delete.js

接下来,让我们尝试从Nodejs程序中运行一个shell脚本

echo 'Hello world'
const { exec } = require("child_process");
cp.exec('./first.sh', (error, stdout, stderr) => {
  // catch err, stdout, stderr
    if (error) {
        console.log('Error in removing files');
        return;
    }
    if (stderr) {
        console.log('an error with file system');
        return;
    }
    console.log('Result of shell script execution',stdout);
});

让我们来看看shell脚本文件的样本first.sh

const { exec } = require("child_process");
cp.exec('./first.sh', (error, stdout, stderr) => {
  // catch err, stdout, stderr
    if (error) {
        console.log('Error in removing files');
        return;
    }
    if (stderr) {
        console.log('an error with file system');
        return;
    }
    console.log('Result of shell script execution',stdout);
});

子进程生成功能

spawn是另一种从nodejs程序执行shell脚本的方式。

它创建新的子进程,执行shell脚本,并使用流API返回数据。由于你正在使用流API,你必须写一个监听器来处理数据。

stdout和stderr是使用流抓取写好的数据,并使用data 事件进行监听。

下面是一个从nodejs程序运行bash脚本文件的示例代码

const cp = require("child_process");

cp.spawn('./first.sh', function(err, stdout, stderr) {

stdout.on("data", data => {
        console.log('Output of script execution');
});

stderr.on("data", data => {
        console.log('an error with file system'');
});

nodejs中的spawn和exec的区别

两者都是用来从nodejs程序中运行脚本或命令,并创建一个新的进程和启动shell窗口。

它们在返回数据的方式上都有区别。

exec将数据存储在执行输出的缓冲区中,而spwn则是将数据流化,并由监听器捕捉数据。

如果脚本文件返回少量的数据,你可以使用exec进程。 spawn最适合于脚本返回大量的数据。

Nodejs ShellJS模块

ShellJS是一个npm库,用于在跨平台上使用javascript代码运行UNIX命令。

它提供了一个名为shx的命令行工具,在全局或本地项目中安装它之后

首先,安装库

npm i shelljs --save

这个包提供了以下unix命令,作为命令行的一部分,也可以从javascript中运行;

  • 触摸
  • cat
  • rm
  • 其中
  • cd
  • cp,如果你想检查java是否安装在unix机器上。
var shell = require('shelljs');

if (!shell.which('java')) {
  shell.echo('Java version is not installed');
  shell.exit(1);
}

要从一个目录中删除文件,你可以使用

shell.rm('-rf', 'dist/public');

递归地从一个目录复制文件到另一个目录

shell.cp('-R', 'dist/', 'release');

或者你可以在命令行中使用上述同样的方法。shx tool

$ shx which java
$ shx rm -rf dist/public
$ shx cp -R dist release

有了这种方法,就不需要写bash或shell脚本文件了,相反,你可以从javascript代码中控制一切。