NSTask et NSPipe
Chacha
Membre
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:
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
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 "A" | 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:@"/bin/ps"];<br /> [psTask setArguments:[NSArray arrayWithObject:@"-x"]];<br /> [psTask setStandardOutput:ps2grepPipe];<br /> <br /> NSTask* grepTask = [[NSTask alloc] init];<br /> [grepTask setLaunchPath:@"/usr/bin/grep"];<br /> [grepTask setArguments:[NSArray arrayWithObject:@"\"A\""]];<br /> [grepTask setStandardInput:ps2grepPipe];<br /> [grepTask setStandardOutput:grep2sortPipe];<br /> <br /> NSTask* sortTask = [[NSTask alloc] init];<br /> [sortTask setLaunchPath:@"/usr/bin/sort"];<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]) && [data length])<br />  NSLog(@"data = %@", data);<br /> NSLog(@"done");<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
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Ok, je peux déjà répondre à ma première question.
Il faut écrire
Pas besoin des quotes. Mouais, c'est pas clair cette histoire.
1- tu as besoins des "", sinon, tu lances une autre commande :
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.
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.
Je crois au contraire que je fais ce qu'il faut : ça marche très bien.
Ben c'est le principe du pipe, la sortie de l'une est pipée en entrée de l'autre...
Ce sont des commandes destinées à être pipées, je ne vois pas trop quel est le problème ?
Nan, d'un point de vue unixien, les "| grep | sort" ne sont pas des arguments du premier programme de la chaà®ne.
+
Chacha
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...
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.)
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 ?
[edit]
Y'en a trouver