
我正在為涉及 Unix 命令列的教程準備一些課程材料 (PDF)。因為我努力實現自動化(有人稱之為懶惰),所以我寫了一個小包,允許我使用\write18
(with --shell-escape
) 和verbatim
包來
ls
在命令處運行命令(例如)期間編譯我的.tex
文檔並將其排版在我的文檔中,- 將結果重定向
stdout
到stderr
外部文件, - 輸入這些外部文件以在我的文件中排版
stdout
和。stderr
.tex
但是,我的理解是每次呼叫都會\write18
開啟和關閉自己的 shell 會話。這是不幸的,因為它需要一些扭曲和程式碼重複。尤其,
- 在一個會話期間定義的所有 shell 變數在下一個會話中都不可用;
- 我必須
cd
在每個檔案開頭的同一目錄中\write18
才能返回到前一個檔案結尾時所在的相同目錄\write18
。
請參閱下面我的玩具範例。
有什麼方法可以在pdflatex
運行期間與 shell 交互,但以某種方式使 shell 會話從一個\write18
呼叫到下一個呼叫保持開啟狀態?或者有更好的方法可以滿足我的需求嗎?
\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}
答案1
\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)設定一個「伺服器」來接受指令,我只使用命名管道:
$ cd /tmp
$ mkfifo zzpipe
$ while true ; do eval `cat /tmp/zzpipe` >/tmp/result.txt ; done
然後運行上面的tex檔案(在/tmp
或安排result.txt
在其他地方寫入)輸出應該如圖所示。
這是在具有 cygwin bash 的 Windows 上,其他命令列將類似,但可能需要不同的引用約定。正如您所看到的,cd
和 的設定FOO
從一個寫入到另一個仍然存在。
答案2
我添加了基本的 bash 支援pythontex
...最終只用了不到 20 行程式碼。要使用此功能,您需要以下版本的最新版本GitHub。pythontex
每當您有需要執行的新 bash 程式碼(執行 LaTeX、執行 PythonTeX 腳本、執行 LateX)時,您都需要使用標準的三步驟編譯。當你沒有需要執行的新程式碼時,你可以直接執行 LaTeX 本身。由於這不使用\write18
,因此您不需要 shell 轉義(程式碼執行由 PythonTeX 腳本處理)。
一切似乎都正常,但如果發現任何錯誤,您必須告訴我。錯誤行號應與所執行程式碼的行號正確同步。
這是一個範例文檔,其輸出如下所示。 \stdoutpythontex
預設是逐字記錄的,因此不必像使用\printpythontex
(或等效的\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}