Gibt es eine Möglichkeit, mit der Shell zu interagieren, aber dieselbe Sitzung geöffnet zu halten?

Gibt es eine Möglichkeit, mit der Shell zu interagieren, aber dieselbe Sitzung geöffnet zu halten?

Ich bereite gerade Kursmaterial (PDF) für ein Tutorial vor, das sich mit der Unix-Befehlszeile beschäftigt. Da ich nach Automatisierung strebe (manche nennen das Faulheit), habe ich ein kleines Paket geschrieben, das es mir ermöglicht, mit \write18(with --shell-escape) und dem verbatimPaket

  1. Führen Sie Befehle aus (z. B. ls) auf BefehlwährendZusammenstellung meines .texDokuments und deren Satz in meinem Dokument,
  2. die resultierenden stdoutund stderrin externe Dateien umleiten,
  3. Geben Sie diese externen Dateien für den Satz stdoutund stderrin meinem .texDokument ein.

Meines Wissens nach \write18öffnet und schließt jedoch jeder Aufruf von seine eigene Shell-Sitzung. Das ist bedauerlich, da es einige Verrenkungen und Code-Duplikationen erfordert. Insbesondere

  • alle während einer Sitzung definierten Shell-Variablen sind in der nächsten nicht verfügbar;
  • Ich muss cdam Anfang jedes einzelnen Befehls in dasselbe Verzeichnis wechseln, \write18um wieder im selben Verzeichnis zu landen, in dem ich mich am Ende des vorhergehenden Befehls befunden habe \write18.

Siehe mein Spielzeugbeispiel unten.

Gibt es eine Möglichkeit, während eines pdflatexLaufs mit der Shell zu interagieren, aber trotzdem eine Shell-Sitzung von einem \write18Aufruf zum nächsten offen zu halten? Oder gibt es einen besseren Ansatz, der meinen Anforderungen entspricht?

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

Antwort1

Bildbeschreibung hier eingeben

\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) Richten Sie einen „Server“ ein, der die Befehle entgegennimmt. Ich verwende einfach eine benannte Pipe:

$ cd /tmp


$ mkfifo zzpipe

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

Führen Sie dann die obige Tex-Datei aus (in /tmpoder Arrange result.txtwird sie woanders geschrieben). Die Ausgabe sollte wie gezeigt aussehen.

Dies gilt für Windows mit Cygwin Bash. Andere Befehlszeilen sind ähnlich, erfordern aber möglicherweise andere Anführungszeichenkonventionen. Und wie Sie sehen, bleibt cddie Einstellung FOOvon einem Schreibvorgang zum anderen erhalten.

Antwort2

Ich habe grundlegende Bash-Unterstützung hinzugefügt, um pythontex... und habe dafür weniger als 20 Zeilen Code benötigt. Um dies zu verwenden, benötigen Sie die neueste Version vonGitHub. Sie müssen die standardmäßige pythontex3-Schritt-Kompilierung verwenden, wenn Sie neuen Bash-Code haben, der ausgeführt werden muss (LaTeX ausführen, das PythonTeX-Skript ausführen, LateX ausführen). Wenn Sie keinen neuen Code haben, der ausgeführt werden muss, können Sie LaTeX einfach selbst ausführen. Da dies nicht verwendet \write18, benötigen Sie kein Shell-Escape (die Codeausführung wird vom PythonTeX-Skript übernommen).

Alles scheint zu funktionieren, aber Sie müssen mich informieren, wenn Sie Fehler finden. Die Zeilennummern der Fehler sollten korrekt mit denen des ausgeführten Codes synchronisiert sein.

Hier ist ein Beispieldokument mit der unten gezeigten Ausgabe. \stdoutpythontexist standardmäßig wörtlich, das Format muss also nicht wie bei \printpythontex(oder dem Äquivalent \stdoutpythontex) angegeben werden.

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

Bildbeschreibung hier eingeben

verwandte Informationen