Comment lancer un sous-processus pendant la compilation ?#

Vous avez peut-être constaté que vous parle de la commande \write18 au début de chaque compilation. Cette commande sert à exécuter un sous-programme à partir de Voici comment :

1.  La commande \write18#

La primitive \write est utilisée pour écrire dans différents « flux » de fichiers. fait référence à chaque fichier ouvert par un numéro, non par un nom de fichier. À l’origine, écrivait dans un fichier connecté à un flux numéroté de 0 à 15. Plus récemment, un « flux 18 » spécial a été implémenté : il n’écrit pas dans un fichier mais indique à de demander au système d’exploitation de faire quelque chose. Pour exécuter une commande, il faut la placer comme argument de \write18. Ainsi, pour exécuter l’utilitaire epstopdf sur un fichier dont le nom est stocké sous la forme \epsfilename, nous écririons :

\write18{epstopdf \epsfilename}

Lorsque vous utilisez par exemple l’extension epstopdf (elle-même appelée quand vous utilisez pdftricks pour utiliser du code PSTricks avec ), l’opération d’écriture « des flux » est cachée et vous n’avez pas à vous soucier de la manière exacte dont elle est faite.

2.  Les problèmes associés à cette commande#

Si vous téléchargez du code ou à partir d’Internet, il pourrait très bien contenir des commandes (peut-être cachées) pouvant nuire à votre ordinateur (comme supprimer tous les fichiers de votre disque dur ou envoyer son contenu à un serveur distant). Face à ce problème, et Live ont, depuis un certain temps, désactivé \write18 par défaut. Pour la réactiver, les deux distributions prennent en charge un argument supplémentaire lors du démarrage de à partir de la ligne de commande :

(pdf)(la)tex --shell-escape ⟨file⟩

Le problème de cette méthode vient du fait que beaucoup d’utilisateurs utilisent et par le biais d’un éditeur graphique. Aussi, pour utiliser \write18 avec un fichier, les paramètres de l’éditeur doivent être modifiés. Mais il faut penser à modifier ces paramètres après le traitement du fichier : sans cela, les bénéfices de la protection d’origine sont perdus…

Dans leurs versions récentes, ces distributions ( à partir de la version 2.9 et Live à partir de la version 2010) contournent ce problème en proposant une version « limitée » de \write18, prête à l’emploi. L’idée est de n’autoriser qu’une liste prédéfinie de commandes (par exemple, epstopdf, lui-même, etc.). Hors de cette liste, toute commande (telle la suppression de fichiers) doit encore être autorisé par l’utilisateur. Cela semble être un bon équilibre : la plupart du temps, la plupart des gens n’auront pas du tout à se soucier de \write18, mais il sera disponible pour epstopdf et autres.

Notez que le système peut vous dire que le mécanisme est en cours d’utilisation, en indiquant au démarrage :

This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex)
 restricted \write18 enabled.

3.  Régler son éditeur pour compiler avec l’option shell-escape#

3.1.  studio#

  1. Dans le menu Options, cliquer sur Configurer studio et sélectionner Production.

  2. Dans le champ Compilation utilisateur, cliquer sur Ajouter.

  3. Compléter le champ de gauche avec : user0: shell escape.

  4. Compléter le champ de droite avec: pdflatex -synctex=1 -interaction=nonstopmode --shell-escape %.tex*.

  5. On peut maintenant lancer une compilation avec l’option shell-escape en pressant les touches ALT + MAJ + F1 ou bien dans le menu outils puis utilisateur.

3.2.  Texmaker#

  1. Se rendre dans le menu Utilisateur puis Commandes utilisateur et Éditer commandes utilisateur.

  2. Dans le champ Item menus , indiquer le nom de son choix, par exemple: shell escape.

  3. Dans le champ commande, indiquer : pdflatex -synctex=1 -interaction=nonstopmode --shell-escape %.tex.

Et voilà! pour compiler avec l’option shell-escape, il suffira maintenant de presser la touche F1.

3.3.  emacs#

Dans le fichier init.el ajouter le code suivant :

(define-minor-mode tex-command-shell-escape-mode 
    "Active la compilation avec -shell-escape"
    :init-value nil
    :lighter " shell-escape"
    (setq  TeX-command-extra-options
           (if (string-empty-p  TeX-command-extra-options)
               "-shell-escape"
             "")))
(bind-key "C-c C-t e" #'tex-command-shell-escape-mode LaTeX-mode-map)

Vous pouvez maintenant activer ou désactiver l’option shell-escape avec C-c C-t e.

4.  Comment récupérer la sortie du sous-processus ?#

Dans son usage le plus commun, le sous-processus lancé depuis va produire un résultat (code tableau de données…) que vous voudrez récupérer pour l’utiliser dans votre document.

Il est possible de passer par des fichiers temporaires, récupérables avec la commande \input :

\immediate\write18{ls *.data > listefichiers.tmp}
\input{listefichiers.tmp}

Ceci permet éventuellement de récupérer plusieurs fichiers.

Si le sous-processus envoie ses résultats sur sa sortie standard, il existe une syntaxe simple pour les récupérer sans passer par un fichier intermédiaire (ajoutée vers 2013 aux différents moteurs ) :

\input|"ls -1 *.data"

Ceci inclura la sortie de la commande ls -1 *.data dans votre document.

Notez qu’il reste indispensable d’utiliser l’option --shell-escape du compilateur pour autoriser le lancement du sous-processus, sinon vous aurez une erreur ressemblant à ceci :

runpopen command not allowed : ls

! I can't find file `"|ls -1 *.data"'.
l.4 \input|"ls -1 *.data

La commande \immediate fait que le \write18 est exécuté immédiatement. Sinon, il ne le serait qu’au moment où la page en cours est envoyée vers la sortie (ce comportement par défaut de \write permet de n’écrire des fichiers externes qu’une fois que les numéros des pages sont fixés).