在Grunt任务中运行命令

97
我正在使用JavaScript项目的任务型命令行构建工具Grunt。我创建了一个自定义标签,并想知道是否可能在其中运行命令。
为澄清起见,我试图使用Closure Templates,"the task"应该调用jar文件来将Soy文件预编译为JavaScript文件。
我正在从命令行运行此jar文件,但我想将它设置为一个任务。
6个回答

106

或者,您可以加载Grunt插件来帮助解决此问题:

grunt-shell 示例:

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

或者grunt-exec的例子:

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
  }
}

9
有人知道这两个软件在Windows上可用吗? - Capaj
我无法立即让 grunt-shell 在 Windows+Cygwin 上工作,但是我使用 grunt-exec 更加顺利。 - Nathan
3
有没有一种同步使用grunt-exec的方法?将命令链接在一起会很方便。 - funseiki
1
@funseiki 只需将命令放在批处理或 shell 中,然后按照您喜欢的顺序调用命令。或者您可以定义任务,例如 mycmds,并编写 "exec:cmd1", "exec:cmd2",这样您也可以同步执行命令。 - Sebastian

37

查看 grunt.util.spawn

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

5
通过 opts: {stdio: 'inherit'},你可以看到命令的输出。 - JuanPablo
2
注意:cmd参数应该是字符串而不是数组。 - RKI
1
现在需要 grunt-legacy-util 插件。它建议使用 require('child_process').spawn() 代替。 - J.D.

21

我已经找到一个解决方案,现在我想与大家分享。

我正在使用Node下的grunt,若要调用终端命令,需要引入'child_process'模块。

例如:

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

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

12
更好的做法是使用插件(或自己编写插件),将您的grunt配置保持为配置而不是代码。grunt-shell和grunt-exec是两个示例。 - papercowboy
由于您在Windows上使用sh mayCommand.sh之前加了sh,我不确定它是否能正常工作。 - svassr
它不会起作用,因为它是Bash脚本。我正在Unix操作系统下运行。 - JuanO

18
如果您正在使用最新的grunt版本(在撰写本文时为0.4.0rc7),则grunt-exec和grunt-shell都会失败(它们似乎没有更新以处理最新的grunt)。另一方面,child_process的exec是异步的,这很麻烦。
最终我使用了Jake Trent的解决方案,并将shelljs作为我的项目的开发依赖项添加,这样我就可以轻松地同步运行测试。
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');
});

1
FYI,“grunt-shell”在Windows下与“grunt v0.4.5”完美兼容。 - fiat
我认为使用shelljs是一个很好的解决方案,因为它使你的node应用程序能够访问shell,并且比仅使用grunt插件更加精细地控制它。 - Nick Steele

17

小伙子们指出了child_process,但是尝试使用execSync来查看输出结果。

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

没有任何额外插件的绝妙解决方案。 - valentinvieriu
我一直在尝试运行任务一整天,终于找到了一个简单有效的解决方案! - johnny 5

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接