使用NSTask启动启动Node.JS的shell脚本

时间:2013-10-04 14:22:46

标签: xcode node.js cocoa shell nstask

我有一个cocoa应用程序,我想启动一个启动Node.js的shell脚本。我想我会用NSTask

做到这一点
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/bash/start.sh"];
[task setArguments:[NSArray arrayWithObjects:@"start.sh", nil]];
[task setStandardOutput:[NSPipe pipe]];
[task setStandardInput:[NSPipe pipe]];

[task launch];

脚本位于我的应用程序的根目录中。我在发射路径上尝试了很多变化而且我被卡住了。任何帮助将不胜感激!

编辑:

这是我设置参数的新代码。它仍然不会出于某种原因。

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/bash"];
[task setArguments:[NSArray arrayWithObjects:[[NSBundle mainBundle] pathForResource:@"start" ofType:@"sh"], nil]];
[task launch];

3 个答案:

答案 0 :(得分:2)

正如您所猜测的,问题在于您的发布路径。

启动路径必须是文件的单一路径。文件名不起作用*,并且您不能在同一路径中命名两个单独的文件。

您的启动路径应该是bash的完整绝对路径。在终端中使用which bash找出哪一个。 (应该在OS X安装的库存上进行/ bin / bash。)

要告诉bash运行脚本,您需要在参数中标识它。只是说剧本的名字不会削减它;你必须给出脚本完整的绝对路径。没有理由在任何地方单独使用脚本的文件名。

我认为脚本是应用程序包中的资源。要获得绝对路径,请your main bundle the URL to that resource,然后get that URL's path

(您可以直接询问a path for a resource,但使用URL是一种值得开发的习惯。如果您需要具体的优势,基于URL的方法正确地将其第二个参数称为文件扩展名,而不是“类型” “;”类型“表示在现代使用中有所不同。”


*文件名被视为任何其他相对路径。相对路径可以工作,但需要解析为相对于当前工作目录存在的路径。默认情况下,这是/(根目录),因此任何可用的相对路径在功能上等同于绝对路径。你应该在任何地方使用绝对路径。

答案 1 :(得分:1)

你应该试试这个:

NSString *path = [[NSBundle mainBundle] pathForResource:@"SCRIPT_NAME" ofType:@"sh"];
NSString *commandToRun =[NSString stringWithFormat:@"/usr/bin/osascript -e\
                         'do shell script \"%@ args 2>&1 etc\" with administrator\
                         privileges'",path];
NSArray *arguments = [NSArray arrayWithObjects:
                      @"-c" ,
                      [NSString stringWithFormat:@"%@", commandToRun],
                      nil];
[task setLaunchPath:@"/bin/sh"];
[task setArguments:arguments];

[task launch];
[task waitUntilExit];               // wait for completion
if ([task terminationStatus] != 0)  // check termination status
{
    NSLog(@"termination status is %d",[task terminationStatus]);

}

如果terminationStatus!= 0,则任务有问题。有问题,你应该查看脚本。

答案 2 :(得分:0)

我有同样的问题,这就是我解决它的方法。假设您正在使用捆绑应用程序,您可以向NSBundle询问应用程序可执行文件的路径。如果您的脚本与可执行文件(<name>.app/Contents/MacOS/)位于同一目录中,那么这应该可以。

NSString *wd = [[NSBundle mainBundle] executablePath];
// this creates a path to <name.app>/Contents/MacOS/<name>/../script, where <name>
//    is the name of your app's executable file
NSString *path = @"/../script";
NSString *fullPath = [wd stringByAppendingString: path ];

[scriptTask setLaunchPath: fullPath];
[scriptTask launch];