问题:
在Meteor中,我如何从客户端调用一个方法(传递name
),让服务器执行一些shell命令?
这个方法函数基本上是:创建一个目录,然后使用给定的name
克隆git repo。
这是非常简单的东西,但Meteor就是不行。我已经困惑了几个小时。在普通的bash或node中都可以正常工作。当前状态:
目录被创建 -> 服务器重新启动 -> Meteor抛出错误,声称该目录已经存在 -> Meteor删除该目录 -> 服务器重新启动
代码:
var cmd, exec, fs;
if (Meteor.isClient) {
Template.app.events({
'click button': function() {
Meteor.call('clone', "NAMEHERE", function(error, result) {
if (error) {
console.log(error);
} else {
console.log(result);
}
});
}
});
}
if (Meteor.isServer) {
fs = Npm.require('fs');
exec = Npm.require('child_process').exec;
cmd = Meteor.wrapAsync(exec);
Meteor.methods({
'clone': function(name) {
var dir;
dir = process.env.PWD + "/projects/" + name;
cmd("mkdir " + dir + "; git clone git@gitlab.com:username/" + name + ".git " + dir, Meteor.bindEnvironment(function(error, stdout, stderr) {
if (error) {
throw new Meteor.Error('error...');
} else {
console.log('done');
}
}));
return 'cloning...';
}
});
}
更新 1
如果我事先手动创建文件夹,则以下代码将成功克隆存储库:
if (Meteor.isClient) {
Template.all.events({
'click button': function() {
Meteor.call('clone', this.name);
}
});
}
if (Meteor.isServer) {
exec = Npm.require('child_process').exec;
cmd = Meteor.wrapAsync(exec);
Meteor.methods({
'clone': function(name) {
var dir, res;
dir = process.env.PWD + "/projects/" + name;
res = cmd(git clone git@gitlab.com:username/" + name + ".git " + dir);
return res;
}
});
}
然而,如果我在cmd中添加"mkdir "+dir,我仍然有同样的问题:目录被创建 -> 服务器重启 -> Meteor抛出一个错误,声称目录已经存在 -> Meteor删除目录 -> 服务器重启
解决办法:Meteor之所以重新启动是因为其目录中的某些内容发生了变化(projects)。该方法随后在启动时重新运行。这是一个与方法调用不相关的问题。update 1 / @Rebolon的代码是解决方案。