NSTask et NSPipe

ChachaChacha Membre
22:53 modifié dans API AppKit #1
Comme c'est étonnant : j'ai du mal avec les NSPipe. J'ai cru comprendre qu'il y avait des spécialistes dans le coin, alors je viens pleurer un peu.
Voilà , je voudrais récupérer le résultat d'une commande Unix composée, du genre "ps -x | grep "A" | sort"
En vrai, ce n'est pas cette commande là  que je veux exécuter (qui est à  base de ps2pdf), mais j'en prend une bateau pour l'exemple.

Le code que j'ai écrit est le suivant:
<br />  //Je veux récupérer le résultat de ps -x | grep &quot;A&quot; | sort<br /><br />  NSPipe* ps2grepPipe       = [NSPipe  pipe];<br />  NSPipe* grep2sortPipe     = [NSPipe  pipe];<br />  NSPipe* outPipe           = [NSPipe  pipe];<br />  NSFileHandle* readHandle  = [outPipe fileHandleForReading];<br />  <br />  NSTask* psTask = [[NSTask alloc] init];<br />  [psTask setLaunchPath:@&quot;/bin/ps&quot;];<br />  [psTask setArguments:[NSArray arrayWithObject:@&quot;-x&quot;]];<br />  [psTask setStandardOutput:ps2grepPipe];<br />  <br />  NSTask* grepTask = [[NSTask alloc] init];<br />  [grepTask setLaunchPath:@&quot;/usr/bin/grep&quot;];<br />  [grepTask setArguments:[NSArray arrayWithObject:@&quot;&#092;&quot;A&#092;&quot;&quot;]];<br />  [grepTask setStandardInput:ps2grepPipe];<br />  [grepTask setStandardOutput:grep2sortPipe];<br />  <br />  NSTask* sortTask = [[NSTask alloc] init];<br />  [sortTask setLaunchPath:@&quot;/usr/bin/sort&quot;];<br />  [sortTask setStandardInput:grep2sortPipe];<br />  [sortTask setStandardOutput:outPipe];<br />  <br />  [psTask   launch];<br />  [grepTask launch];<br />  [sortTask launch];<br />  <br />  NSData* data = nil;<br />  while((data = [readHandle availableData]) &amp;&amp; [data length])<br />    NSLog(@&quot;data = %@&quot;, data);<br />  NSLog(@&quot;done&quot;);<br />  <br />  [psTask   release];<br />  [grepTask release];<br />  [sortTask release];<br />


Vous vous en doutez, ça ne marche pas, (data ne se remplit jamais) sinon je ne serais pas en train de geindre. J'ai essayé de déplacer les launch, les setStandardInput/Output, de rajouter des waitUntilExit, mais décidément, rien à  faire. Quelqu'un peut-il éclairer ma lanterne ?


Question n°2
Comme vous pouvez le voir, dans l'exemple ci-dessus, le chemin de "ps", "grep" et "sort" est codé en dur, ce qui est mal. Comme je n'ai pas trouvé de fonction Cocoa qui le fasse, je m'en suis créé une qui me renvoie le chemin d'une commande unix, selon le principe suivant:
-soit <toto> la commande à  trouver
-j'exécute un "/usr/bin/which toto"
-je récupère le résultat (via un pipe... qui marche dans ce cas là !)

Cela vous semble-t-il acceptable ?  Y'a-t-il mieux à  faire ?

Merci d'avance

+
Chacha

Réponses

  • ChachaChacha Membre
    22:53 modifié #2
    dans 1111312767:

    <br />  [grepTask setLaunchPath:@&quot;/usr/bin/grep&quot;];<br />  [grepTask setArguments:[NSArray arrayWithObject:@&quot;&#092;&quot;A&#092;&quot;&quot;]];<br />
    



    Ok, je peux déjà  répondre à  ma première question.
    Il faut écrire
    <br />  [grepTask setLaunchPath:@&quot;/usr/bin/grep&quot;];<br />  [grepTask setArguments:[NSArray arrayWithObject:@&quot;A&quot;]];<br />
    


    Pas besoin des quotes. Mouais, c'est pas clair cette histoire.
  • fouffouf Membre
    22:53 modifié #3
    Bon,
    1- tu as besoins des "", sinon, tu lances une autre commande :
    -A NUM, --after-context=NUM
                  Print NUM lines of trailing context after matching lines.


    2- je pense que tu te plantes compétement :
    La, tu lance 3 tasks à  la suites, des tasks qui n'ont rien à  voir entre elles. Tu crées un input pour grep alors qu'il ne réponds pas quand on lui envoie des infos durant son fonctionnement. (essaye juste de faire grep "A" dans le terminal, puis essaye d'ecrire des choses, il ne renverra rien).Pareil pour sort.

    Je pense que tu peux te dépatouiller en ne faisant qu'un NSTask correspondant à  ps puis mettre les autres en arguments.
  • ChachaChacha Membre
    mars 2005 modifié #4
    dans 1111490313:

    Bon,
    1- tu as besoins des "", sinon, tu lances une autre commande :


    Apparement, non. Quand j'ai dit que je n'avais pas besoin des quotes, c'est surtout parce que si je les enlève, ça marche !
    Je pense que ça s'explique finalement assez facilement: sous un shell, metter les quote, simple ou double permet d'utiliser (ou non) l'expansion des variables, etc. Via une NSTask, les arguments sont des chaà®nes statiques, où aucune expansion ne sera faite, les quotes sont donc inutiles. Si je le mets, le grep va cherche des lignes contenant des quotes ! Et dans mon cas, comme il n'y en avait pas, la sortie était vide.


    2- je pense que tu te plantes compétement :

    Je crois au contraire que je fais ce qu'il faut : ça marche très bien.


    La, tu lance 3 tasks à  la suites, des tasks qui n'ont rien à  voir entre elles.

    Ben c'est le principe du pipe, la sortie de l'une est pipée en entrée de l'autre...


    Tu crées un input pour grep alors qu'il ne réponds pas quand on lui envoie des infos durant son fonctionnement. (essaye juste de faire grep "A" dans le terminal, puis essaye d'ecrire des choses, il ne renverra rien).Pareil pour sort.

    Ce sont des commandes destinées à  être pipées, je ne vois pas trop quel est le problème ?


    Je pense que tu peux te dépatouiller en ne faisant qu'un NSTask correspondant à  ps puis mettre les autres en arguments.

    Nan, d'un point de vue unixien, les "| grep | sort" ne sont pas des arguments du premier programme de la chaà®ne.

    +
    Chacha
  • fouffouf Membre
    22:53 modifié #5
    Et si tu enlevais les releases des tasks ?
  • cbrandtcbrandt Membre
    22:53 modifié #6
    chez moi ça marche parfaitement... y'a juste l'affichage du nsdata à  améliorer:
    <br />&nbsp; NSLog(@&quot;data = %@&quot;, [[[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding] autorelease]);<br />
    


    mais là  c'est juste parce qu'on sait que le résultat est du texte...

    si le résultat n'est pas censé être du texte, y'a rien d'autre à  faire...
  • fouffouf Membre
    22:53 modifié #7
    Alors, as-tu réussi à  faire marcher tout ca ?
  • ChachaChacha Membre
    22:53 modifié #8
    dans 1112202161:

    Alors, as-tu réussi à  faire marcher tout ca ?

    Mais oui, dès le deuxième post j'expliquais que finalement j'avais réussi à  faire fonctionner... simplement j'expliquais pourquoi il y avait eu un problème, à  cause des double quotes.
    Comme de par hasard, mes NSTask, on les retrouve dans LaTeXiT; et elles marchent bien (pour latex et dvips au moins; pour epstopdf, il y a encore un mystère à  l'heure où j'écris ces lignes, d'autant qu'en cas d'échec de la NSTask, un system() prend le relais, et vu qu'il foire tout autant, il doit y avoir un problème plus profond.)
  • fouffouf Membre
    22:53 modifié #9
    Peut-etre que ca peut marcher si tu attends que le dvips soit fini (tu récupères ca avec NSTaskDidTerminateNotification ) puis ensuite lancer le NSTask epstopdf ?
  • ChachaChacha Membre
    mars 2005 modifié #10
    dans 1112204888:

    Peut-etre que ca peut marcher si tu attends que le dvips soit fini (tu récupères ca avec NSTaskDidTerminateNotification ) puis ensuite lancer le NSTask epstopdf ?

    Je ne pense pas que le problème vienne des NSTask, puisque chez moi ça fonctionne. Mais il faudrait que je voie les logs reportés dans la console par la dernière version. Tu les as ?
  • fouffouf Membre
    mars 2005 modifié #11
    Je les cherche. J'essaye de t'envoyer ca ce soir.

    [edit]
    Y'en a trouver
Connectez-vous ou Inscrivez-vous pour répondre.