Cocoa运行已包含双引号的AppleScript

时间:2013-11-03 22:48:40

标签: cocoa applescript sh

我有一个需要管理员权限来执行cmd的Cocoa应用程序, 但在某些极端情况下,如包含双引号的文件名,此代码不起作用。

 NSString *fileName = @"~/Documents/My\" File/";
 NSString *cmd = [NSString stringWithFormat:@"chown -R '%@' '%@';NSUserName(), fileName];
 NSString *cmd_execute = [NSString stringWithFormat:@"do shell script
 \"%@\" with administrator privileges",cmd_execute]; 
//This line is the problem, our %@ contains double quote, so cocoa 
//cannot interpret correctly.

1 个答案:

答案 0 :(得分:2)

以下是使用NSAppleScript将参数传递到AppleScript处理程序的正确方法:

// load/compile AppleScript
NSAppleScript *scpt = [[NSAppleScript alloc] initWithSource:
        @"on joinText(a, b)\n"
        @"  return a & b\n"
        @"end addTo"];

NSString *arg1 = @"Hello ";
NSString *arg2 = @"World!";

// pack positional parameters
NSAppleEventDescriptor *params = [NSAppleEventDescriptor listDescriptor];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg1] atIndex: 1];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg2] atIndex: 2];

// build Apple event to invoke user-defined handler in script
NSAppleEventDescriptor *eventDesc = [NSAppleEventDescriptor appleEventWithEventClass: 'ascr'
                                                            eventID: 'psbr'
                                                            targetDescriptor: [NSAppleEventDescriptor nullDescriptor]
                                                            returnID: 0
                                                            transactionID: 0];
[eventDesc setDescriptor: params forKeyword: '----'];
[eventDesc setDescriptor: [NSAppleEventDescriptor descriptorWithString: @"joinText"] forKeyword: 'snam'];

 // invoke handler
 NSDictionary *errorInfo = nil;
 NSAppleEventDescriptor *resultDesc = [scpt executeAppleEvent: eventDesc error: &errorInfo];
 if (resultDesc)
     NSLog(@"Result: %@\n", [resultDesc stringValue]);
 else
     NSLog(@"Error: %@\n", errorInfo);

这样就无需动态地编写和编译AS脚本 - 正如您的原始ObjC代码所示,这是一个很好的机会,可能会因为消毒不足而在您的程序中引入错误和安全漏洞。

...

以下是在AppleScript中组装shell脚本字符串的正确方法:

do shell script ("chown -R " & quoted form of username & " " & quoted form of filepath)

AppleScript的do shell script命令不提供传递参数的安全机制(它在许多其他方面也存在缺陷),但AS字符串具有quoted form属性,至少返回引用和适用于连接到shell脚本字符串的文本的转义版本。

...

当然,通过do shell script AppleScript调用shell只是为了运行chmod升级的priveleges本身并不是一点点hacky,尽管这主要是因为Apple没有提供 simple < / em>这样做的官方API(例如,通过向NSUserScriptTask添加“使用管理员权限运行”选项)。

Apple确实提供了一个示例项目SMJobBless,该项目展示了如何使用Service Management框架和launchd添加和运行特权进程。但这是一个足够复杂的解决方案,许多人会(有意或无意地)偷工减料或完全做错事,这相当于在一开始就提供了一种安全的做事方式。但你需要与Apple合作。