我有一个需要管理员权限来执行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.
答案 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合作。