Synchronisation d'exécutions
(Sous OS x)
Très exactement, je fais exécuter un script dans le terminal en utilisant un AppleScript que je compile et que je fais exécuter comme ça (extrait):
monScript = [[NSAppleScript alloc] initWithSource:laplescript ] ;
marche = [monScript compileAndReturnError:&infoErreur] ;
descripteur = [monScript executeAndReturnError:&infoErreur] ; // Compilation Exécution
........... etc
le script lui-même:
Tell application "Terminal"
do script " ici la liste des commandes "
end tell
Problème, l'exécution du script prend de 30 s à 1 mn et mon programme n'attend pas la fin de son exécution pour enchainer.
J'ai une solution: Je crée un fichier vide avant de lancer le script, j'ajoute à la fin des commandes un: rm le-nom-du-fichier, puis j'ajoute après le lancement du script une boucle d'attente de la suppression de ce fichier. ça marche, mais forcément ça ralentit l'ensemble !
Quelles autres solutions voyez-vous ?
Réponses
C'est un peu l'artillerie lourde d'utiliser un AppleScript pour exécuter un script en ligne de commandes.
Le plus simple si tu dois attendre la fin de l'exécution, et si celle-ci n'est pas trop longue est d'utiliser la commande system(3).
Si la commande est un peu longue, et qu'on veut pouvoir faire autre chose en attendant la fin, ou simplement ne pas bloquer les actions utilisateurs, il faut utiliser NSTask. Il y a tout ce qui faut pour synchroniser la tâche là dedans.
Ok, merci. Je vais voir ça.
ouais ! ça marche, à un truc près que je ne comprend pas. Le "working directory" à l'appel de "system" est le dossier ou est le programme qui fait l'appel ! Normalement les fonctions du shell sont dans /bin, /sbin, /usr/bin, /usr/local/bin ...... etc.
si j'écris:
command = @pwd ; cd \hatari\ ; pwd"
int xx = system(command.UTF8String) ;
Le premier pwd m'indique bien le dossier de l'exécutable, mais le deuxième pwd me donne une erreur du genre "pwd n'existe pas" !
Si je fais la même chose dans le terminal les deux fonctionnent correctement !
Une petite explication ?
Ceci dit je suis arrivé à faire ce que je voulais, il me reste à mettre en place un pipe pour afficher ce qui se passe.
C'est sans doute que la variable d'environnement PATH n'est pas initialisée par la commande system, donc les commandes sont recherchées dans le dossier courant.
Lors du lancement, c'est le shell sh qui s'exécute, qui est dans le dossier /bin. La commande pwd se trouve dans le même dossier : elle est trouvée et exécutée.
Lorsque tu changes de dossier courant, la commande pwd n'est plus trouvée.
La solution est soit d'initialiser la variable PATH en début de liste de commandes, soit d'expliciter le chemin complet de chaque commande, p.ex. /bin/pwd.
Bonjour,
Il faudrait voir le code exact et la sortie exacte. Dans l'exemple donné il y a des backslashs au milieu de la chaine. J'imagine que cela peut poser problème au shell (à moins que cela soit voulu...).
En réalisant un test rapide en C, tout fonctionne comme prévu.
Effectivement je n'ai pas initialiser le PATH, ce que je vais faire.
Lexxis, j'ai oublié une guillemet dans la commande reportée ci-dessus.
command: @pwd ; cd \hatari\" ; pwd"
et (command.UTF8String) = pwd ; cd "hatari" ; pwd
La variable PATH est théoriquement déjà initialisé sinon ton premier pwd ne fonctionnerait pas. (tu peux ajouter un echo $PATH; en début de commande pour voir cela).
C'est plutôt étrange comme erreur. Tu l'as systématiquement ? Peut être l'erreur as-t-elle un rapport avec le dossier hatari plutôt que la commande pwd ?
Les "pwd" que j'avais mis étaient là pour vérifier les chemins d'accès. Comme tout marche bien maintenant, je les ai supprimé ! Comme je ne fais rien de payant, je vous mets le projet (pas terminé) ci-dessous. Il s'agit de l'automatisation de l'accès à l'émulateur Hatari (téléchargement, paramétrage, compilations). Mercurial et CMake doivent être installés ainsi que les bibliothèques annexes (SDL, SDL2, png, ....etc). Et ne râlez pas ! ma programmation n'a probablement rien à voir avec la vôtre car je ne suis pas informaticien du tout !
Je reprends ce post car j'ai suivi le conseil de JPImbert et je suis passé à NSTask !
J'ai quatre tâches a faire exécuter successivement! ça marche, sauf pour la troisième tâche.
Comment avec NSTask fait-on exécuter un script ?
J'ai varié les appels, les paramètres..etc, je n'y arrive pas ! soit je bloque l'appli, soit l'application appelée me dit que le script n'existe pas !
Je mets en annexe ce foutu script zipé !