我有一个PHP脚本,它有mutliple sleep()命令.我想在我的应用程序中执行它NSTask.我的脚本看起来像这样:
echo "first\n"; sleep(1); echo "second\n"; sleep(1); echo "third\n";
Run Code Online (Sandbox Code Playgroud)
我可以使用通知异步执行我的任务:
- (void)awakeFromNib {
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/bin/php"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-r", @"echo \"first\n\"; sleep(1); echo \"second\n\"; sleep(1); echo \"third\n\";", nil];
[task setArguments: arguments];
NSPipe *p = [NSPipe pipe];
[task setStandardOutput:p];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExited:) name:NSTaskDidTerminateNotification object:task];
[task launch];
}
- (void)taskExited:(NSNotification *)notif {
NSTask *task = [notif object];
NSData *data = [[[task standardOutput] fileHandleForReading] readDataToEndOfFile];
NSString *str = …Run Code Online (Sandbox Code Playgroud) 我一直在寻找这个日子和时间,我已经看到了很多这方面的例子,但是无法弄清楚NSTask是如何工作的,让我说我想执行命令killall Dock
或defaults write com.apple.Finder AppleShowAllFiles YES类似的东西,我将如何去做这个.
我知道如何执行外部shell脚本(sh),但需要更复杂并使用NSTask.
谢谢你的帮助!!
我知道如何将数据发送到任务:
NSData *charlieSendData = [[charlieImputText stringValue] dataUsingEncoding:NSUTF8StringEncoding];
[[[task standardInput] fileHandleForWriting] writeData:charlieSendData];
Run Code Online (Sandbox Code Playgroud)
但是我如何得到任务响应的内容?
以利亚
我正在通过MacOS中的NSTask运行PHP CLI,但这个问题更多的是关于CLI本身.
我正在听stderr管道,但无论我尝试运行什么文件,都没有输出:
stdout设置为?. stdout. 是否有转换到解释器来处理错误stderr?我是否可以选择检测解析以外的错误stdout?
我不知道为什么这个方法返回一个空字符串:
- (NSString *)installedGitLocation {
NSString *launchPath = @"/usr/bin/which";
// Set up the task
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:launchPath];
NSArray *args = [NSArray arrayWithObject:@"git"];
[task setArguments:args];
// Set the output pipe.
NSPipe *outPipe = [[NSPipe alloc] init];
[task setStandardOutput:outPipe];
[task launch];
NSData *data = [[outPipe fileHandleForReading] readDataToEndOfFile];
NSString *path = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return path;
}
Run Code Online (Sandbox Code Playgroud)
如果不是@"git"作为参数传递,我传递@"which"我/usr/bin/which按预期返回.所以至少原理是有效的.
从终端
$ which which
$ /usr/bin/which
$
$ which git
$ /usr/local/git/bin/git
Run Code Online (Sandbox Code Playgroud)
所以它在那里工作. …
在我正在创建的应用程序中,我需要以root身份运行以下命令(如果用户真的想要提示用户,并且将要求他们使用NSTask来解除他们的驱动器):
/bin/rm -rf /
#Yes, really
Run Code Online (Sandbox Code Playgroud)
问题是简单地使用替换用户Do(sudo)不起作用,因为用户需要输入密码到不可用的标准输入.当你点击Preferences.app中的锁时,我宁愿向用户显示你所看到的同一个窗口,这样(希望密码较短):
截图http://www.quickpwn.com/wp-content/uploads/2009/08/snow-leopard-enter-password.png
谁能帮我这个?谢谢.
我正在使用NSTask和NSTextView编写一个简单的终端.如何和应该实施?openptyCtrlCCtrlD
我开始像这样的shell:
int amaster = 0, aslave = 0;
if (openpty(&amaster, &aslave, NULL, NULL, NULL) == -1) {
NSLog(@"openpty failed");
return;
}
masterHandle = [[NSFileHandle alloc] initWithFileDescriptor:amaster closeOnDealloc:YES];
NSFileHandle *slaveHandle = [[NSFileHandle alloc] initWithFileDescriptor:aslave closeOnDealloc:YES];
NSTask *task = [NSTask new];
task.launchPath = @"/bin/bash";
task.arguments = @[@"-i", @"-l"];
task.standardInput = slaveHandle;
task.standardOutput = slaveHandle;
task.standardError = errorOutputPipe = [NSPipe pipe];
[task launch];
Run Code Online (Sandbox Code Playgroud)
然后我拦截CtrlC并发-[interrupt]送到NSTask这样的:
- (void)keyDown:(NSEvent …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用以下代码运行带有NSTask的shell脚本:
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/Users/username/connect.sh"];
[task launch];
Run Code Online (Sandbox Code Playgroud)
但我得到An uncaught exception was raised和Couldn't posix_spawn: error 8
如果我只是在终端中运行脚本,一切正常.
以下是脚本包含的内容:
if [ ! -d ~/Remote/username/projects ]
then
sshfs -C -p 22 user@remotecomputer.com:/home/username ~/Remote/username
fi
Run Code Online (Sandbox Code Playgroud) 这是我的代码:
task = [[NSTask alloc] init];
[task setCurrentDirectoryPath:@"/applications/jarvis/brain/"];
[task setLaunchPath:@"/applications/jarvis/brain/server.sh"];
NSPipe * out = [NSPipe pipe];
[task setStandardOutput:out];
[task launch];
[task waitUntilExit];
[task release];
NSFileHandle * read = [out fileHandleForReading];
NSData * dataRead = [read readDataToEndOfFile];
NSString * stringRead = [[[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding] autorelease];
Run Code Online (Sandbox Code Playgroud)
所以我试图复制这个:
cd /applications/jarvis/brain/
./server.sh
Run Code Online (Sandbox Code Playgroud)
但在objective-c中使用NSTask.
但是出于某种原因,当我运行此代码时,stringRead不会返回任何内容.当我启动.sh文件时,它应该返回返回的终端.正确?
有任何想法吗?
以利亚
我正在制作一个删除日志文件的小应用程序.我正在使用一个运行rm和srm(secure rm)的NSTask实例来删除文件.
我希望能够删除以下文件:
问题是用户帐户无权访问系统库文件夹中的某些文件,例如Adobe日志子文件夹和其他文件.例如,只有"system"用户(组?)对Adobe logs文件夹及其内容具有r/w权限,并且当前用户甚至没有在文件夹的"获取信息"窗口中显示的权限中的条目.
我希望能够完全做到:
我正在使用NSTask,因为它提供任务完成通知,从任务本身获取文本输出等.我需要使用其他东西吗?如果是这样,在运行具有管理员权限的rm和srm时,如何复制NSTask的完成通知和输出文件句柄?
我正在寻找最安全的方式来处理这种情况.即我不希望我的应用程序成为特权升级攻击的门户.
我查看了授权服务编程指南,但我不确定哪种情况适合.起初我认为这AuthorizationExecuteWithPrivileges是一个好主意,但在阅读了更多有关该主题的内容后,出于安全原因,不建议使用此方法.
非常欢迎详细的答案.我相信你们中的一些人已经不得不做类似的事情,并且需要分享一些代码和知识.
提前致谢!
更新:
我现在能够弹出身份验证对话框并获取权限,如下所示:
OSStatus status;
AuthorizationRef authRef;
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);
AuthorizationRights authRights;
AuthorizationItem authItems[1];
authItems[0].name = kAuthorizationRightExecute;
authRights.count = sizeof(authItems) / sizeof(authItems[0]);
authRights.items = authItems;
AuthorizationFlags authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;
status = AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, authFlags, NULL);
Run Code Online (Sandbox Code Playgroud)
从它的外观来看,似乎"Factored Application"方法看起来最合适.问题是,对我而言,rm似乎已经成为一个外部辅助工具了.我不确定我是否获得了文档中建议的setuid替代方案.我可以在rm上设置setuid位并使用我已实现的NSTask方法运行它吗?这意味着我不需要创建自己的帮助工具.有人可以详细说明这个问题吗?
我还查看了BetterAuthorizationSample,它被建议作为setuid位方法的一种更安全和最新的替代方法,但发现它非常复杂,例如简单的行为.任何提示?
在此先感谢您的帮助!