Existe alguma maneira de interagir com o shell, mas manter a mesma sessão aberta?

Existe alguma maneira de interagir com o shell, mas manter a mesma sessão aberta?

Estou preparando algum material de curso (PDF) para um tutorial que envolve a linha de comando do Unix. Como eu busco a automação (alguns chamam isso de preguiça), escrevi um pequeno pacote que me permite, usando \write18(with --shell-escape) e o verbatimpacote,

  1. execute comandos (por exemplo ls) no comandodurantecompilação do meu .texdocumento e digitá-los no meu documento,
  2. redirecionar o resultante stdoute stderrpara arquivos externos,
  3. insira esses arquivos externos para composição tipográfica stdoute stderrem meu .texdocumento.

No entanto, meu entendimento é que cada invocação \write18abre e fecha sua própria sessão de shell. Isto é lamentável, pois requer algumas contorções e duplicação de código. Em particular,

  • todas as variáveis ​​de shell definidas durante uma sessão ficam indisponíveis na próxima;
  • Eu tenho que cdir para o mesmo diretório no início de cada um \write18para voltar ao mesmo diretório em que estava no final do anterior \write18.

Veja meu exemplo de brinquedo abaixo.

Existe alguma maneira de interagir com o shell durante uma pdflatexexecução, mas de alguma forma manter uma sessão do shell aberta de uma \write18chamada para outra? Ou existe uma abordagem melhor que atenda às minhas necessidades?

\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}

Responder1

insira a descrição da imagem aqui

\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 um "servidor" para aceitar os comandos, apenas uso um pipe nomeado:

$ cd /tmp


$ mkfifo zzpipe

$ while true ; do eval `cat /tmp/zzpipe` >/tmp/result.txt  ; done

em seguida, execute o arquivo tex acima ( /tmpou o arranjo result.txté escrito em outro lugar). A saída deve ser conforme mostrado.

Isso ocorre no Windows com cygwin bash, outras linhas de comando serão semelhantes, mas podem precisar de convenções de cotação diferentes. e como você pode ver, cda configuração de FOOsobrevive de uma gravação para a outra.

Responder2

Eu adicionei suporte básico ao bash para pythontex... acabei ocupando menos de 20 linhas de código. Para usar isso, você precisará da versão mais recente doGitHub. Você precisará usar a pythontexcompilação padrão de 3 etapas sempre que tiver um novo código bash que precisa ser executado (execute o LaTeX, execute o script PythonTeX, execute o LateX). Quando você não tem um novo código que precisa ser executado, você pode simplesmente executar o LaTeX sozinho. Como isso não usa \write18, você não precisa de shell-escape (a execução do código é controlada pelo script PythonTeX).

Tudo parece estar funcionando, mas você deverá me avisar se encontrar algum bug. Os números das linhas de erro devem ser sincronizados corretamente com os do código executado.

Aqui está um documento de amostra, com a saída mostrada abaixo. \stdoutpythontexé literalmente por padrão, portanto, o formato não precisa ser especificado como acontece com \printpythontex(ou 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}

insira a descrição da imagem aqui

informação relacionada