Différences entre Shell et Exec

Shell

SHELL invoque /bin/sh et lui passe une ligne de commande unique. /bin/sh interprète cette ligne de commande exactement de la même manière que si vous l’aviez passée à un shell normal. Ainsi,

SHELL "ls -l *.o >/tmp/list"

Fera exactement comme si vous tapiez ls -l \*.o >*tmp/list dans un émulateur de terminal à l’intérieur d’un shell. C’est beaucoup de choses, car le shell est d’une puissance formidable. Cette commande effectue :

  1. Le découpage de la commande en plusieurs parties : exécutable à lancer, paramètres à lui transmettre, autres constructions...

  2. La recherche d’un exécutable nommé ls dans l’environnement PATH.

  3. Substitution de *.o par tous les fichiers .o files dans le répertoire en cours.

  4. Préparation d’une redirection (la sortie normale de /bin/ls est redirigée vers /tmp/list).

Pour faire court, le shell peut faire beaucoup de choses, et la commande Gambas vous donne ce pouvoir.

Une fois que /bin/sh a terminé ce travail de découpage et d’interprétation, il effectue un appel système exec(), qui charge et lance un exécutable en lui passant un certain nombre de paramètres.

Exec

L’instruction EXEC de Gambas effectue l’appel système exec(), en court-circuitant le shell (/bin/sh). C’est plus rapide et moins gourmand en mémoire, parce que vous invoquez une commande externe sans invoquer /bin/sh, mais vous perdez toute la puissance du shell.

En fait, si vous deviez lister tous les fichiers .o dans le répertoire en cours et mettre le résultat dans /tmp/list sans recourir à la puissance du shell, vous auriez à faire par vous-même :

  1. La recherche des fichiers.

  2. La création d’un tableau des noms de ces fichiers.

  3. L’invocation de /bin/ls en lui passant un tableau contenant le -l et tous les fichiers que vous avez trouvés.

  4. La redirection vers un fichier de sortie standard, ou l’utilisation de la syntaxe FOR pour obtenir la sortie directe dans un gestionnaire d’évènements Gambas.

En conclusion, si vous lancez un EXEC dans Gambas, vous n’avez simplement qu’à fournir le nom du programme à exécuter et ses paramètres. Si vous émettez :

EXEC ["/bin/ls", "-l", "*.o", ">/tmp/list"]

Vous invoquerez /bin/ls en lui passant les paramètres ci-dessus. /bin/ls reconnaîtra (correctement) l’option -l, mais *.o et >/tmp/list seront reconnus comme des fichiers à rechercher, et aucun fichier nommé *.o n’existera. Le >/tmp/list est une syntaxe shell, et non pas une syntaxe de /bin/ls, et /bin/ls cherchera à nouveau le fichier nommé >/tmp/list.

Vous pouvez taper man sh à l’invite du shell ; tout ce que vous lirez là décrit les capacités du shell, et aucune d’entre elles ne sont disponibles avec EXEC. Les trois choses les plus importantes disponibles dans le shell, et pas dans EXEC, sont :

  1. La substitution de motif. *.o et semblables sont des constructions shell.

  2. La redirection et les tubes. >/foo/bar, </foo/bar, 2>&1 | command etc…

  3. Les variables telles que $HOME, $PATH etc.

Mais EXEC possède un bon avantage sur le SHELL. Si vous devez invoquer une commande externe qui possède (ou peut avoir) des caractères inhabituels dans la ligne de commande, comme

firefox http://someserver.com/doit.cgi?name=foo&reply=bar

Le SHELL (ou, mieux, /bin/sh) interprétera les caractères comme ? et &, alors qu’EXEC ne le fera pas.

Donc, s’il vous faut une aptitude du shell, utilisez SHELL ; sinon, employez EXEC. L’utilisation de SHELL économise des frappes, par ailleurs, pour peu que vous soyez sûr qu’aucun caractère bizarre (?, &, $, espaces, et autres) ne peut apparaître dans la commande que vous construisez.

Dans ce dernier cas, Gambas possède une fonction Quote.Shell() qui met entre guillemets ces caractères "bizarres" pour l'instruction SHELL, de sorte que vous êtes assuré que n’importe quel nom de fichier peut être utilisé.

Voir aussi