1

NSTaskを使用してUNIXの「apropos」コマンドを実行しようとしています。これが私のコードです:

NSTask *apropos = [[NSTask alloc] init];
NSPipe *pipe = [[NSPipe alloc] init];
[apropos setLaunchPath:@"/usr/bin/apropos"];
[apropos setArguments:[NSArray arrayWithObjects:@"filename", @"match", nil]];
[apropos setStandardOutput:pipe];
[apropos launch];
[apropos waitUntilExit];

問題は、これが二度と戻らないことです。また、Appleのサンプルコード(TaskWrapper)を使用してみましたが、出力(3つのセグメント)が返されますが、processFinishedハンドラーが呼び出されることはありません。

さらに、appendOutput:ハンドラーは重複を受け取ります。したがって、たとえば、aproposがこれを返す場合:

1 2 3 4 5

私はこのようなものを受け取るかもしれません:

1 2 3

1 2 3 4

5

(3つの追加メッセージにグループ化されます)。

Aproposは、データを直接標準出力に直接出力するのではなく、コマンドラインで上下にスクロールできる形式で出力を表示することに注意してください。NSTaskとNSPipeを介してこれを確実に読み取るにはどうすればよいですか?

4

2 に答える 2

3

このプログラムをテストしたところ、正常に動作しています。プログラムは終了し/tmp/apropos.txt、の出力が含まれていますapropos

#import <Foundation/Foundation.h>

int main()
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    NSTask *apropos = [[[NSTask alloc] init] autorelease];
    NSPipe *pipe = [[[NSPipe alloc] init] autorelease];
    NSFileHandle *readHandle = [pipe fileHandleForReading];
    [apropos setLaunchPath:@"/usr/bin/apropos"];
    [apropos setArguments:[NSArray arrayWithObjects:@"filename", @"match", nil]];
    [apropos setStandardOutput:pipe];
    [apropos launch];
    [apropos waitUntilExit];

    NSString *output = [[[NSString alloc]
        initWithData:[readHandle readDataToEndOfFile]
            encoding:NSUTF8StringEncoding] autorelease];

    [output writeToFile:@"/tmp/apropos.txt" atomically:YES
        encoding:NSUTF8StringEncoding error:NULL];

    [pool drain];
    return 0;
}

万が一NSLog()、出力の検査に使用していますか?もしそうなら、NSTask関連の質問への私のこの回答でstdin説明されているようにパイプを設定する必要があるかもしれません。にデータを送信すると影響があるようです。NSLog()stderrNSTask

于 2011-01-22T02:00:49.373 に答える
2

元のコードでは、コマンドの出力を読み取っていないためだと思います。パイプのバッファーサイズは限られており、タスクの出力を読み取らないと、バッファーが空になるのを待ってハングする可能性があります。あなたが試したサンプルコードについては何も知らないので、そこでは仕方がありません。最後の質問はapropos、端末に接続されている場合にのみポケットベルを使用します。端末をエミュレートしていないので、心配する必要はありません。apropos whatever | catこれは、ターミナルで実行し、ポケットベルが呼び出されていないことを確認することで証明できます。

于 2011-01-22T01:35:00.273 に答える