
Estoy preparando material del curso (PDF) para un tutorial que involucra la línea de comandos de Unix. Debido a que me esfuerzo por la automatización (algunos llaman a eso pereza), he escrito un pequeño paquete que me permite, usando \write18
(with --shell-escape
) y el verbatim
paquete,
- ejecutar comandos (por ejemplo
ls
) en el comandodurantecompilación de mi.tex
documento y componerlos en mi documento, - redirigir el resultado
stdout
ystderr
a archivos externos, - Ingrese esos archivos externos para componer el
stdout
ystderr
en mi.tex
documento.
Sin embargo, tengo entendido que cada invocación \write18
abre y cierra su propia sesión de shell. Esto es desafortunado, ya que requiere algunas contorsiones y duplicación de código. En particular,
- todas las variables de shell definidas durante una sesión no están disponibles en la siguiente;
- Tengo que
cd
ir al mismo directorio al principio de cada uno\write18
para volver al mismo directorio en el que estaba al final del anterior\write18
.
Vea mi ejemplo de juguete a continuación.
¿Hay alguna manera de poder interactuar con el Shell durante una pdflatex
ejecución, pero de alguna manera mantener abierta una sesión de Shell de una \write18
llamada a la siguiente? ¿O existe un enfoque mejor que se adapte a mis necesidades?
\documentclass{article}
\usepackage{lipsum}
\begin{document}
First, initialise the repository.
% pretend that the following is an environment that both
% - runs commands at the CL
% - typesets them in the .tex document
\immediate\write18{%
cd $HOME/Desktop;
mkdir myrepo;
cd myrepo;
git init;
}
Let's see what git has to say...
\immediate\write18{%
# I'm back in $HOME :(
# I have to cd to $HOME/Desktop/myrepo, here, but I'd like to avoid it...
cd $HOME/Desktop/myrepo;
git status
# ...
}
\end{document}
Respuesta1
\documentclass{article}
\begin{document}
\immediate\write18{echo pwd > /tmp/zzpipe}
\texttt{\input{result.txt}}
\immediate\write18{echo cd > /tmp/zzpipe}
\immediate\write18{echo pwd > /tmp/zzpipe}
\texttt{\input{result.txt}}
\immediate\write18{echo 'FOO=wibble' > /tmp/zzpipe}
\immediate\write18{echo 'echo FOO is $FOO' > /tmp/zzpipe}
\texttt{\input{result.txt}}
\end{document}
a) configurar un "servidor" para aceptar los comandos, solo uso una canalización con nombre:
$ cd /tmp
$ mkfifo zzpipe
$ while true ; do eval `cat /tmp/zzpipe` >/tmp/result.txt ; done
luego ejecute el archivo tex anterior (en /tmp
u organizar result.txt
se escribe en otro lugar) el resultado debería ser como se muestra.
Esto es en Windows con cygwin bash, otras líneas de comando serán similares pero pueden necesitar convenciones de comillas diferentes. y como puede ver, la cd
configuración y la configuración FOO
sobreviven de una escritura a la otra.
Respuesta2
Agregué soporte básico de bash para pythontex
... terminé tomando menos de 20 líneas de código. Para utilizar esto, necesitará la última versión deGitHub. Deberá utilizar la pythontex
compilación estándar de 3 pasos siempre que tenga un nuevo código bash que deba ejecutarse (ejecute LaTeX, ejecute el script PythonTeX, ejecute LateX). Cuando no tenga código nuevo que deba ejecutarse, puede ejecutar LaTeX por sí solo. Como esto no usa \write18
, no necesita Shell-escape (la ejecución del código se maneja mediante el script PythonTeX).
Todo parece estar funcionando, pero tendrás que avisarme si encuentras algún error. Los números de línea de error deben sincronizarse correctamente con los del código que se ejecuta.
A continuación se muestra un documento de muestra, cuyo resultado se muestra a continuación. \stdoutpythontex
es palabra por palabra de forma predeterminada, por lo que no es necesario especificar el formato como lo hace con \printpythontex
(o su equivalente \stdoutpythontex
).
\documentclass{article}
\usepackage[makestderr, usefamily=bash]{pythontex}
\setpythontexfv{numbers=left, firstnumber=last}
\begin{document}
A block of bash...
\begin{bashblock}
myvar="myvar's value"
echo $myvar
\end{bashblock}
...with output:
\printpythontex[verbatim]
Another block, accessing the previous variable...
\begin{bashblock}
echo "In another LaTeX environment later on..."
echo $myvar
\end{bashblock}
...with output:
\printpythontex[verbatim]
A block with an error.
\begin{bashblock}
echo "In another LaTeX environment later on..."
echo $myvar
lsERROR
\end{bashblock}
Stdout:
\printpythontex[verbatim]
Stderr:
\stderrpythontex
\end{document}