Domanda

Sto cercando di utilizzare NSTask per eseguire il comando UNIX 'apropos'. Ecco il mio codice:

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];

Il problema è che questo non ritorna mai. Ho anche provato ad utilizzare codice di esempio di Apple (TaskWrapper) e restituisce l'output (in tre segmenti), ma non è mai chiama il gestore processFinished.

Inoltre, l'appendOutput: gestore riceve i duplicati. Così, per esempio, se i rendimenti apropos questo:

1 2 3 4 5

Potrei ricevere qualcosa di simile:

1 2 3

1 2 3 4

5

(raggruppati in 3 messaggi di aggiunta).

rilevo che Apropos visualizza l'output in un formato in cui è possibile scorrere su e giù nella linea di comando invece di emettere direttamente i dati direttamente nell'output standard; Come faccio a leggere questo modo affidabile attraverso NSTask e NSPipe?

È stato utile?

Soluzione

Ho appena testato questo programma e funziona bene:. I termina programma e /tmp/apropos.txt contiene l'output del 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;
}

Sei per caso utilizzando NSLog() per ispezionare l'uscita? Se è così, potrebbe essere necessario impostare un tubo per stdin come spiegato in questa risposta di miniera per un NSTask correlata domanda . Sembra che NSLog() invio dei dati al stderr colpisce NSTask.

Altri suggerimenti

Con il codice originale, immagino che sia perché non state leggendo l'output del comando. I tubi hanno solo una dimensione di buffer limitato, e se non avete letto l'uscita del compito, si può finire in attesa appeso per il buffer a svuotarsi. Io non so nulla circa il codice di esempio si è tentato così io non ci posso fare a meno. Per quanto riguarda l'ultima domanda, apropos utilizza solo il cercapersone quando è collegato ad un terminale. Non stai emulando un terminale, in modo che non ci si deve preoccupare. È possibile dimostrare questo eseguendo apropos whatever | cat nel terminale e verificare che il cercapersone non viene richiamato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top