Running a command in a Grunt Task

69,678

Solution 1

I've found a solution so I'd like to share with you.

I'm using grunt under node so, to call terminal commands you need to require 'child_process' module.

For example,

var myTerminal = require("child_process").exec,
    commandToBeExecuted = "sh myCommand.sh";

myTerminal(commandToBeExecuted, function(error, stdout, stderr) {
    if (!error) {
         //do something
    }
});

Solution 2

Alternatively you could load in grunt plugins to help this:

grunt-shell example:

shell: {
  make_directory: {
    command: 'mkdir test'
  }
}

or grunt-exec example:

exec: {
  remove_logs: {
    command: 'rm -f *.log'
  },
  list_files: {
    command: 'ls -l **',
    stdout: true
  },
  echo_grunt_version: {
    command: function(grunt) { return 'echo ' + grunt.version; },
    stdout: true
  }
}

Solution 3

Check out grunt.util.spawn:

grunt.util.spawn({
  cmd: 'rm',
  args: ['-rf', '/tmp'],
}, function done() {
  grunt.log.ok('/tmp deleted');
});

Solution 4

If you are using the latest grunt version (0.4.0rc7 at the time of this writing) both grunt-exec and grunt-shell fail (they don't seem to be updated to handle the latest grunt). On the other hand, child_process's exec is async, which is a hassle.

I ended up using Jake Trent's solution, and adding shelljs as a dev dependency on my project so I could just run tests easily and synchronously:

var shell = require('shelljs');

...

grunt.registerTask('jquery', "download jquery bundle", function() {
  shell.exec('wget http://jqueryui.com/download/jquery-ui-1.7.3.custom.zip');
});

Solution 5

Guys are pointing child_process, but try to use execSync to see output..

grunt.registerTask('test', '', function () {
        var exec = require('child_process').execSync;
        var result = exec("phpunit -c phpunit.xml", { encoding: 'utf8' });
        grunt.log.writeln(result);
});
Share:
69,678
JuanO
Author by

JuanO

On my 10+ years of experience in IT I have worked as a technical lead for major companies. Worked for different branches of the software industry itself such as software for the retail industry, e-commerce platforms and banking industry - ensuring they meet any required security standards -. I can describe myself in two parts. The guy who's enthusiast and enjoys to be a programmer willing to have the best application performance, scalable and with an excellent architecture design. Or the guy who is a team leader and also enjoys client managing, projects leadership giving warranty for delivery dates. Being capable of influencing a large team or multiple projects to achieve goals (30+ teams) I'm always willing to learn top edged technologies and adapt them in problem solving applications focused on client orientation results.

Updated on July 14, 2020

Comments

  • JuanO
    JuanO almost 4 years

    I'm using Grunt (task-based command line build tool for JavaScript projects) in my project. I've created a custom tag and I am wondering if it is possible to run a command into it.

    To clarify, I'm trying to use Closure Templates and "the task" should call the jar file to pre-compile the Soy file to a javascript file.

    I'm running this jar from command line, but I want to set it as a task.

  • papercowboy
    papercowboy over 11 years
    A better approach is to use a plugin (or write your own) to keep your grunt config as config and not code. grunt-shell & grunt-exec are two examples.
  • Capaj
    Capaj about 11 years
    Does anyone know if either of those two is usable on Windows?
  • svassr
    svassr over 10 years
    As you use sh before sh mayCommand.sh I'm not sure it would work on windows
  • JuanO
    JuanO over 10 years
    It won't work because it's bash scripting. I'm running under Unix OS's
  • Nathan
    Nathan over 10 years
    I could not immediately get grunt-shell to work with Windows+Cygwin but I had better luck with grunt-exec.
  • funseiki
    funseiki about 10 years
    Is there a way to use grunt-exec synchronously? It would be nice to chain commands together
  • JuanPablo
    JuanPablo almost 10 years
    with opts: {stdio: 'inherit'}, you can see the output of command
  • Sebastian
    Sebastian almost 10 years
    @funseiki just put the commands inside a batch or shell which calls the commands in you preferred order. Or you define task e.g. mycmds and write "exec:cmd1", "exec:cmd2" then you also have synchronously order.
  • fiat
    fiat almost 9 years
    fyi grunt-shell is working fine with grunt v0.4.5 under Windows
  • Nick Steele
    Nick Steele over 8 years
    I think using shelljs is a great solution because it enables your node app to access the shell, and it gives you finer control over it than the grunt addons alone.
  • RKI
    RKI over 8 years
    Note: cmd param should be a string not an array.
  • J.D.
    J.D. almost 8 years
    This now requires the grunt-legacy-util plugin. It recommends using require('child_process').spawn() instead.
  • valentinvieriu
    valentinvieriu almost 8 years
    Great solution without any additional plugins.
  • johnny 5
    johnny 5 almost 6 years
    I've been trying to get run running tasks for a day, and finally a simple solution that works!