Ajarudin Gunga
Ajarudin Gunga

Reputation: 453

How to execute sequential base commands in nodejs?

I need to run 4 bash commands sequentially in nodejs.

set +o history
sed -i 's/&& !this.peekStartsWith('\/\/')/ /g' dist/vendor.bundle.js
sed -i 's/&& !this.peekStartsWith('\/\/')/ /g' dist/vendor.bundle.js.map
set -o history

how this could be achieved? or is it possible to add in npm script?

Upvotes: 3

Views: 2189

Answers (2)

Kousha
Kousha

Reputation: 36299

To extend @melc's answer, to execute the requests sequentially, you can do:

const {promisify} = require('util');
const {exec} = require('child_process');
const execAsync = promisify(exec);

const sequentialExecution = async (...commands) => {
  if (commands.length === 0) {
    return 0;
  }

  const {stderr} = await execAsync(commands.shift());
  if (stderr) {
    throw stderr;
  }

  return sequentialExecution(...commands);
}

// Will execute the commands in series
sequentialExecution(
  "set +o history",
  "sed -i 's/&& !this.peekStartsWith('\/\/')/ /g' dist/vendor.bundle.js",
  "sed -i 's/&& !this.peekStartsWith('\/\/')/ /g' dist/vendor.bundle.js.map",
  "set -o history",
);

Or if you don't care about stdout/sterr, you can use the following one-liner:

const commands = [
  "set +o history",
  "sed -i 's/&& !this.peekStartsWith('\/\/')/ /g' dist/vendor.bundle.js",
  "sed -i 's/&& !this.peekStartsWith('\/\/')/ /g' dist/vendor.bundle.js.map",
  "set -o history",
];

await commands.reduce((p, c) => p.then(() => execAsync(c)), Promise.resolve());

Upvotes: 4

melc
melc

Reputation: 11671

To run shell commands from node use exec, https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

Three possible approaches could be,

  1. Create a bash script file containing all needed commands and then run it from node using exec.

  2. Run each command individually from node using exec.

  3. Use an npm package, for example one of the following (I haven't tried them) https://www.npmjs.com/package/shelljs
    https://www.npmjs.com/package/exec-sh

It's also possible to promisify exec (https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original) and use async/await instead of callbacks. For example,

const {promisify} = require('util');
const {exec} = require('child_process');

const execAsync = promisify(exec);

(async () => {
  const {stdout, stderr} = await execAsync('set +o history');
...
})();

Upvotes: 4

Related Questions