繁体   English   中英

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

[英]Using NSTask to launch shell script that launches Node.JS

我有一个可可应用,我想启动一个启动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];

如您所料,问题在于您的启动路径。

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

您的启动路径应该是bash的完整绝对路径。 在终端中使用which bash可以找到哪种。 (在普通的OS X安装中,它应该是/ bin / bash。)

要告诉bash运行脚本,您需要在参数中对其进行标识。 只是说脚本的名字不会减少它。 您必须提供脚本的完整绝对路径。 没有理由将脚本的文件名放在任何地方。

我假设脚本是您的应用程序包中的资源。 要获取其绝对路径,请向您的主捆绑包索要该资源的URL ,然后获取该URL的path

(您可以直接请求资源的路径 ,但是使用URL是值得养成的习惯。如果您需要具体的优势,则基于URL的方法将其第二个参数正确地称为文件名扩展名,而不是“类型”;“类型”表示现代用法有所不同。)


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

您应该尝试这样:

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,则说明任务有问题。 出了点问题,您应该检查脚本。

我遇到了同样的问题,这就是我解决的方法。 假设您正在使用捆绑软件应用程序,则只需向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];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM