58

I would like to run a shell command from gulp, using gulp-shell. I see the following idiom being used the gulpfile.

Is this the idiomatic way to run a command from a gulp task?

var cmd = 'ls';
gulp.src('', {read: false})
    .pipe(shell(cmd, {quiet: true}))
    .on('error', function (err) {
       gutil.log(err);
});
Ben Aston
  • 53,718
  • 65
  • 205
  • 331

5 Answers5

116

gulp-shell has been blacklisted. You should use gulp-exec instead, which has also a better documentation.

For your case it actually states:

Note: If you just want to run a command, just run the command, don't use this plugin:

var exec = require('child_process').exec;

gulp.task('task', function (cb) {
  exec('ping localhost', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
    cb(err);
  });
})
ddprrt
  • 7,424
  • 3
  • 29
  • 25
44

The new way to do this that keeps console output the same (e.g., with colors):

see: https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

var gulp = require('gulp');
var spawn = require('child_process').spawn;

gulp.task('my-task', function (cb) {
  var cmd = spawn('cmd', ['arg1', 'agr2'], {stdio: 'inherit'});
  cmd.on('close', function (code) {
    console.log('my-task exited with code ' + code);
    cb(code);
  });
});
AutoSponge
  • 1,444
  • 10
  • 7
  • 3
    But be careful if you are on Windows, as spawn() doesn't work reliably, see [this Node issue](https://github.com/nodejs/node-v0.x-archive/issues/2318) – Rich Tebb Jan 28 '16 at 16:27
  • 1
    This is the best answer imo +1 – chukkwagon Nov 20 '17 at 14:48
  • 2
    this solution doesn't work for me on windows, but found another one here - https://stackoverflow.com/questions/45841902/how-to-run-ng-build-from-gulp-using-child-process-spawn-or-disable-all-output-in – Sergey Apr 03 '18 at 13:27
  • Excellent answer! I found & created a more verbose method (https://gist.github.com/rmckeel/b4e60922f5098ced9c50bdd96731b34a/ccca5069825096cb286c46c090312f1b5e0d5594), but I updated that code sample with this inherit stdio concept (https://gist.github.com/rmckeel/b4e60922f5098ced9c50bdd96731b34a), because it is elegant and should work for most purposes. Thanks! – ryanm May 07 '18 at 14:46
17

With gulp 4 your tasks can directly return a child process to signal task completion:

'use strict';

var cp = require('child_process');
var gulp = require('gulp');

gulp.task('reset', function() {
  return cp.execFile('git checkout -- .');
});

gulp-v4-running-shell-commands.md

elad.chen
  • 2,375
  • 5
  • 25
  • 37
birnbaum
  • 4,718
  • 28
  • 37
1

You could simply do this:

const { spawn } = require('child_process');
const gulp = require('gulp');

gulp.task('list', function() {
    const cmd = spawn('ls');
    cmd.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });
    return cmd;
});
azerafati
  • 18,215
  • 7
  • 67
  • 72
1

According to Gulp's documentation, you can run a command like echo like this:

const cp = require('child_process');

function childProcessTask() {
  return cp.exec('echo *.js');
}

exports.default = childProcessTask;

exec takes one string that will be parsed by the shell, and it silences output by default.

I personally like using child_process.spawn instead. spawn takes the name of the command, and then a list of arguments. If you use the option stdio: 'inherit' it won't swallow its output.

function childProcessTask() {
  return cp.spawn('echo', ['one', 'two'], {stdio: 'inherit'});
}

References:

Flimm
  • 136,138
  • 45
  • 251
  • 267