Mac OS X Lion上的进程间通信

时间:2012-03-16 18:53:01

标签: objective-c cocoa osx-lion ipc xpc

我正在试图弄清楚如何在我的自定义应用和预制程序之间设置IPC 我正在使用MacOSX Lion 10.7.2和Xcode 4.2.1。

实际上究竟是什么程序并不重要,因为我相信类似的推理可能适用于任何类型的外部过程。
出于测试目的,我使用的是一个简单的bash脚本:

#test.sh
echo "Starting"
while read out 
do 
    echo $out
done

我想要实现的是重定向此脚本的输入和输出,使用我的应用程序向其发送输入并读取其输出。

我尝试使用NSTaskNSPipeNSFileHandle,如下所示:

-(void)awakeFromNib {

    task = [[NSTask alloc] init];

    readPipe = [NSPipe pipe];
    writePipe = [NSPipe pipe];

    [task setStandardOutput:readPipe];
    [task setStandardInput:writePipe];    

    [task setLaunchPath:@"/path/test.sh"];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(read:)
                                                 name:NSFileHandleReadCompletionNotification
                                               object:nil];

    [[readPipe fileHandleForReading] readInBackgroundAndNotify];

    [task launch];

}

-(IBAction)write:(id)sender {

    NSLog(@"Write called: %d %@\n",[task isRunning],writePipe);

    NSFileHandle *writeHandle = [writePipe fileHandleForWriting];

    NSString *message = @"someString";

    [writeHandle writeData:[message dataUsingEncoding:NSUTF8StringEncoding] ];

}

-(void)read:(NSNotification*)notification {

    NSString *output = [[NSString alloc] initWithData:[[notification userInfo] valueForKey: NSFileHandleNotificationDataItem]
                                             encoding:NSUTF8StringEncoding];

    NSLog(@"%@",output);

    [output release];

    [[notification object] readInBackgroundAndNotify]; 

}

但我只能读取test.sh的输出,而不是发送任何输入。

实际上我在网上看到的任何其他例子与我的代码非常相似,所以我不确定这个问题是由于我的一些错误还是其他问题(比如应用程序的MacOS Lion的沙盒)

我已经检查了XPC文档,但根据我的研究,为了将XPC API用于IPC,两个方应连接到同一服务。
这不是我想要的,因为我不想以任何方式改变脚本,我只想重定向其输入和输出。

我的问题是由于缺少XPC和/或应用程序的沙盒而导致的吗?

如果是,是否有办法在不修改脚本的情况下使用XPC?
如果不是,那么可能有人向我解释我做错了什么?

1 个答案:

答案 0 :(得分:1)

你不需要XPC。不会有任何区别。

当您在命令行中管道输入时,您的脚本/外部进程是否能够读取输入

% echo "foobar" | /path/test.sh

您发送给它的数据量是多少。写作将被缓冲。 IIRC -synchronizeFile将刷新缓冲区 - 与fsync(2)相同。