使用具有管理员权限的 AppleScript,"not ask for authentication again for five minutes." 不起作用?
Using AppleScript with administrator privileges, "not ask for authentication again for five minutes." doesn't work?
苹果文档Technical Note 2065中提到"do shell script command with administrator privileges",这样使用时,"Once a script is correctly authenticated, it will not ask for authentication again for five minutes."
但是,还是需要一次又一次的认证。
我发现,在使用ScriptEditor.app的时候,苹果文档是对的。
例如:
do shell script "/bin/cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop/ " with administrator privileges
但是,当使用 NSAppleScript 运行 shell 脚本时,Apple 文档是错误的。
例如:
NSDictionary *error = nil;
NSString *copyScript = @"do shell script \"/bin/cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop \" with administrator privileges";
NSAppleScript *copyAppleScript = [[NSAppleScript alloc] initWithSource:copyScript];
if ([copyAppleScript executeAndReturnError:&error])
{
NSLog(@"copyAppleScript Success!");
}
else
{
NSLog(@"copyAppleScript Failuer!");
}
我希望,当使用 NSAppleScript 执行 shell 脚本时,它也不会在五分钟内再次请求身份验证。
首先,我认为这不是解决此问题的最佳方法。但是让我先回答这个问题,然后再建议另一个途径。
请注意,技术说明 2065 是这样说的:
The authentication only applies to that specific script: a different
script, or a modified version of the same one, will ask for its own
authentication.
每次你运行这一行:
NSAppleScript *copyAppleScript = [[NSAppleScript alloc] initWithSource:copyScript];
...您创建了一个新脚本,该 new 脚本将需要自己的授权。如果您想在不经常重新授权的情况下重复使用给定的脚本,您需要创建一个 NSAppleScript
属性,将您的脚本存储在那里一次,然后重复调用它。换句话说:
@interface MyObject ()
@property (strong) NSAppleScript *myAppleScript;
@end
@implementation MyObject
- (void)setUpScript {
// call this once
NSDictionary *error = nil;
NSString *copyScript = @"do shell script \"/bin/cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop \" with administrator privileges";
self.myAppleScript = [[NSAppleScript alloc] initWithSource:copyScript];
}
- (void)runScript {
// call this as needed; shouldn't need reauthorization
if ([self.myAppleScript executeAndReturnError:&error]) {
NSLog(@"myAppleScript Success!");
} else {
NSLog(@"myAppleScript Failure!");
}
}
@end
但是,由于您的目标是 运行 一个 shell 脚本,我建议您完全忘记 NSAppleScript
,而是使用 NSTask
。 NSTask
是来自 objC 的 shell 脚本的意思 运行,应该完全避免授权问题。最简单的方法是编写一个明确的 shell 脚本并将其存储在包中:
#!/bin/bash
cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop
然后调用 运行 那个 shell 脚本:
NSError *err;
NSTask *task = [NSTask launchedTaskWithExecutableURL:[[NSBundle mainBundle] URLForResource:@"ShellScript"
withExtension:@"sh"]
arguments:[NSArray array]
error:&err
terminationHandler:nil];
...或者,如果您不想捆绑脚本...
NSError *err;
NSTask *task = [[NSTask alloc] init]
task.arguments = [NSArray arrayWithObjects:@"#!/bin/bash",
@"-c",
@"cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop",
nil];
[task launchAndReturnError:&err];
P.S.
我一直假设此 cp
命令只是概念验证,但如果您的实际目标是复制文件,请忘记 NSAppleScript
和 NSTask
。请改用 NSFileManager's
copyItemAtURL:toURL:error:
。
苹果文档Technical Note 2065中提到"do shell script command with administrator privileges",这样使用时,"Once a script is correctly authenticated, it will not ask for authentication again for five minutes."
但是,还是需要一次又一次的认证。
我发现,在使用ScriptEditor.app的时候,苹果文档是对的。
例如:
do shell script "/bin/cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop/ " with administrator privileges
但是,当使用 NSAppleScript 运行 shell 脚本时,Apple 文档是错误的。 例如:
NSDictionary *error = nil;
NSString *copyScript = @"do shell script \"/bin/cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop \" with administrator privileges";
NSAppleScript *copyAppleScript = [[NSAppleScript alloc] initWithSource:copyScript];
if ([copyAppleScript executeAndReturnError:&error])
{
NSLog(@"copyAppleScript Success!");
}
else
{
NSLog(@"copyAppleScript Failuer!");
}
我希望,当使用 NSAppleScript 执行 shell 脚本时,它也不会在五分钟内再次请求身份验证。
首先,我认为这不是解决此问题的最佳方法。但是让我先回答这个问题,然后再建议另一个途径。
请注意,技术说明 2065 是这样说的:
The authentication only applies to that specific script: a different script, or a modified version of the same one, will ask for its own authentication.
每次你运行这一行:
NSAppleScript *copyAppleScript = [[NSAppleScript alloc] initWithSource:copyScript];
...您创建了一个新脚本,该 new 脚本将需要自己的授权。如果您想在不经常重新授权的情况下重复使用给定的脚本,您需要创建一个 NSAppleScript
属性,将您的脚本存储在那里一次,然后重复调用它。换句话说:
@interface MyObject ()
@property (strong) NSAppleScript *myAppleScript;
@end
@implementation MyObject
- (void)setUpScript {
// call this once
NSDictionary *error = nil;
NSString *copyScript = @"do shell script \"/bin/cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop \" with administrator privileges";
self.myAppleScript = [[NSAppleScript alloc] initWithSource:copyScript];
}
- (void)runScript {
// call this as needed; shouldn't need reauthorization
if ([self.myAppleScript executeAndReturnError:&error]) {
NSLog(@"myAppleScript Success!");
} else {
NSLog(@"myAppleScript Failure!");
}
}
@end
但是,由于您的目标是 运行 一个 shell 脚本,我建议您完全忘记 NSAppleScript
,而是使用 NSTask
。 NSTask
是来自 objC 的 shell 脚本的意思 运行,应该完全避免授权问题。最简单的方法是编写一个明确的 shell 脚本并将其存储在包中:
#!/bin/bash
cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop
然后调用 运行 那个 shell 脚本:
NSError *err;
NSTask *task = [NSTask launchedTaskWithExecutableURL:[[NSBundle mainBundle] URLForResource:@"ShellScript"
withExtension:@"sh"]
arguments:[NSArray array]
error:&err
terminationHandler:nil];
...或者,如果您不想捆绑脚本...
NSError *err;
NSTask *task = [[NSTask alloc] init]
task.arguments = [NSArray arrayWithObjects:@"#!/bin/bash",
@"-c",
@"cp -r /Users/Simon/Desktop/Test/test.zip /Users/Simon/Desktop",
nil];
[task launchAndReturnError:&err];
P.S.
我一直假设此 cp
命令只是概念验证,但如果您的实际目标是复制文件,请忘记 NSAppleScript
和 NSTask
。请改用 NSFileManager's
copyItemAtURL:toURL:error:
。