我正在尝试为YouTube-dl工具制作一个GUI。(YouTube-dl.org)我正在使用这个Shell函数来运行必要的命令:
func shell(_ command: String) -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.arguments = ["-c", command]
task.launchPath = "/bin/bash"
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
return output这是我写的代码,当一个按钮被按下时,启动YouTube-dl,给它一个YouTube地址,并将下载的视频保存到桌面:
@IBAction func actionMP4(_ sender: Any) {
shell("/usr/local/bin/youtube-dl -o ~/Desktop/DownloadedVideo.mp4 https://youtu.be/pUECdF7KCN4")
}当我运行程序并按下链接到上面代码的按钮时,我得到这个错误:
/bin/bash: /usr/local/bin/youtube-dl: Operation not permitted我怎么给它权限呢?
谢谢。
发布于 2020-07-09 02:26:09
如果应用程序的目标是支持下载YouTube视频,那么它可能并不真的需要提升权限。如果Youtube-dl需要这样做,它可能不是一个很好的本地Mac应用后端的候选者。更好的选择可能是实现它的功能和/或寻找替代API,使您无需提升权限(或python依赖,就此而言)即可完成此操作。
也就是说,如果您确实希望以提升的权限运行外部工具,则需要使用XPC创建一个特权助手工具,并让用户授权它在运行时以管理员身份运行。这个API在过去的几个操作系统版本中发展了一点,在某种程度上,我认为从设计上讲,实现起来并不容易。
大多数示例代码都是用Objective-C编写的,所以您需要熟悉使用Swift中的Objective-C API,或者用Objective-C编写提升代码,并将其封装在一个可以从Swift轻松调用的类中。提升的工具包装器由launchd作为XPCService启动,您的应用程序通过mach端口与其通信。
完整的代码和项目设置超出了本文的讨论范围,但这里有一个在Objective-C中实现的setup方法的示例,它是EvenBetterAuthorizationSample代码的缩写(删除了注释和诊断说明):
- (void)connectWithEndpointAndAuthorizationReply:(void(^)(NSXPCListenerEndpoint * endpoint, NSData * authorization))reply
{
[self.queue addOperationWithBlock:^{
if (self.helperToolConnection == nil) {
self.helperToolConnection = [[NSXPCConnection alloc] initWithMachServiceName:kHelperToolMachServiceName options:NSXPCConnectionPrivileged];
self.helperToolConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(HelperToolProtocol)];
self.helperToolConnection.invalidationHandler = ^{
self.helperToolConnection.invalidationHandler = nil;
[self.queue addOperationWithBlock:^{
self.helperToolConnection = nil;
NSLog(@"connection invalidated");
}];
};
[self.helperToolConnection resume];
}
[[self.helperToolConnection remoteObjectProxyWithErrorHandler:^(NSError * proxyError) {
NSLog(@"connect failed: %@ / %d", [proxyError domain], (int) [proxyError code]);
reply(nil, nil);
}] connectWithEndpointReply:^(NSXPCListenerEndpoint *replyEndpoint) {
reply(replyEndpoint, self.authorization);
}];
}];
}下面是完整项目示例的当前链接:https://developer.apple.com/library/archive/samplecode/EvenBetterAuthorizationSample/Introduction/Intro.html
苹果开发者论坛的一条帖子说,这应该可以通过Swift:https://developer.apple.com/forums/thread/99151实现。
下面是关于这个主题的另一个SO主题:Application, Helper Tool Communication
https://stackoverflow.com/questions/62800869
复制相似问题