NSTask -> NSPipe -> NSFileHandle ?

tabliertablier Membre
17:44 modifié dans API AppKit #1
je souhaite exécuter :  "/bin/bash -c export AEDebugSends=1;  applicationPath ;  unset AEDebugSends" et récupérer le résultat.
En suivant le modèle donné par Apple, j'ai écrit:
- (void)tacheExec:(NSString *)son_Chemin resultat:(NSMutableData *)cumul
{
NSString   *laCommande ;
NSTask *task;
NSArray *arguments;
NSPipe   *maPipe;
NSFileHandle      *myfile;
NSData *inData;

[cumul setString:@\r] ;
inData = nil ;
                                                                              // son_Chemin = chemin de l'exécutable
  laCommande = [NSString stringWithFormat:@export AEDebugSends=1; %@; unset AEDebugSends", son_Chemin ] ;
arguments = [NSArray arrayWithObjects:@-c, laCommande, nil];

maPipe = [NSPipe pipe];
myfile = [maPipe fileHandleForReading];

task = [[NSTask alloc] init];
[task setLaunchPath: @/bin/bash];
[task setArguments: arguments];
[task setStandardOutput:maPipe ];

[task launch];

while ((inData = [myfile availableData]) && [inData length]) {
[cumul appendData:[NSData dataWithData:inData] ] ;
} ;

[task release] ;
}
L'application se lance bien, mais les résultats s'affichent dans la console au lieu de remplir "cumul". Donc je n'ai pas connecté le pipe à  la sortie des données du NSTask! J'ai beau lire et relire les exemples que j'ai, je ne trouve pas l'erreur!

Help!

Réponses

  • AliGatorAliGator Membre, Modérateur
    17:44 modifié #2
    En passant vite fait par là  j'ai lu en diagonale, comme ca je v pis pas d'erreur, mais peut-etre que ton exécutable que tu lances affiche ses données sur la sortie d'erreur standard (stderr) et non sur la sortie standard (stdout), ce qui expliquerait le comportement.
    En effet sur le Terminal, la sortie standard et l'erreur standard sont toutes les deux affichées à  l'écran dans le même flux ce quittait qu'on ne peut pas les différencier : que l'exécutable lancé dans le terminal écrive sur stdout ou sur stderr, dans les deux cas ça s'affiche pareil dans le terminal... Mais si tu rediriges stdout vers un fichier (mais pas stderr) bah seul ce qui est écrit sur stdout sera donc redirigé (et ce qui est sur stderr restera non redirigé donc continuera de s'afficher dans le terminal).

    Donc là  c'est pareil si ton exécutable écrit sur stderr, tu auras beau rediriger stdout via setStandardOutput, ce qui est écrit sur la StandardError ne sera pas redirigé... Essaye en redirigeant aussi l'erreur standard pour voir du coup.
  • devulderdevulder Membre
    17:44 modifié #3
    dans 1280941227:

    je souhaite exécuter :  "/bin/bash -c export AEDebugSends=1;  applicationPath ;  unset AEDebugSends" et récupérer le résultat.
    En suivant le modèle donné par Apple, j'ai écrit:
    - (void)tacheExec:(NSString *)son_Chemin resultat:(NSMutableData *)cumul
    {
    NSString   *laCommande ;
    NSTask *task;
    NSArray *arguments;
    NSPipe   *maPipe;
    NSFileHandle      *myfile;
    NSData *inData;

    [cumul setString:@\r] ;
    inData = nil ;
                                                                                  // son_Chemin = chemin de l'exécutable
      laCommande = [NSString stringWithFormat:@export AEDebugSends=1; %@; unset AEDebugSends", son_Chemin ] ;
    arguments = [NSArray arrayWithObjects:@-c, laCommande, nil];

    maPipe = [NSPipe pipe];
    myfile = [maPipe fileHandleForReading];

    task = [[NSTask alloc] init];
    [task setLaunchPath: @/bin/bash];
    [task setArguments: arguments];
    [task setStandardOutput:maPipe ];

    [task launch];

    while ((inData = [myfile availableData]) && [inData length]) {
    [cumul appendData:[NSData dataWithData:inData] ] ;
    } ;

    [task release] ;
    }
    L'application se lance bien, mais les résultats s'affichent dans la console au lieu de remplir "cumul". Donc je n'ai pas connecté le pipe à  la sortie des données du NSTask! J'ai beau lire et relire les exemples que j'ai, je ne trouve pas l'erreur!

    Help!


    Bonjour,

    Essaie ca

    [task launch];
    [task waitUntilExit];

    NSData *resultats;

    resultats = [myfile readDataToEndOfFile];

    NSString *res= [[NSString alloc] initWithData:resultats encoding:NSUTF8StringEncoding];

    NSLog(@resultat = %@",res);




  • tabliertablier Membre
    août 2010 modifié #4
    Ok, je vais essayer ce que vous me conseiller ce soir. Là  je ne suis pas chez moi.
  • tabliertablier Membre
    17:44 modifié #5
    J'ai fait les deux, et la fin de la méthode devient:
    task = [[NSTask alloc] init] ;<br />	[task setLaunchPath: @&quot;/bin/bash&quot;] ;<br />	[task setArguments: arguments] ;<br />	[task setStandardOutput:maPipe ] ;<br />	[task setStandardError:maPipe ] ;<br />	<br />	[task launch] ;<br />	[task waitUntilExit] ;<br />	<br />	inData = [myfile readDataToEndOfFile] ;<br />	[task release] ;<br />
    
    et inData contient le texte attendu.
    Il me reste une question: Dans le débugger, je n'arrive plus a voir le contenu des variables après l'exécution de la tâche!! Est-ce que ce serait lié au bug du NSLog? dans la doc on trouve ceci:
    If you are using NSTask to run a command-line utility via bash, then you need to include this magic line to keep NSLog working:
    //The magic line that keeps your log where it belongs
    [task setStandardInput:[NSPipe pipe]];

    In context:

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput: pipe];
    //The magic line that keeps your log where it belongs
    [task setStandardInput:[NSPipe pipe]];
  • tabliertablier Membre
    17:44 modifié #6
      :P  Résultat:
    J'ai ajouté la ligne conseillée comme décrit dans la doc et, Oh merveille, le debugger  accepte de donner les représentations des variables!
Connectez-vous ou Inscrivez-vous pour répondre.