\chapter[Installation]{命令行} 无论是安装还是使用 \CONTEXT,皆需要对命令行环境有所了解。本章先分别介绍 Windows、Linux 和 macOS 系统的命令行环境的基本用法,以刚好满足安装和运行 \CONTEXT\ 环境需求为要。 若你对命令行环境已颇为熟悉,只是想了解如何安装 \CONTEXT,可直接从 \in[installation] 节开始阅读,否则要有耐心从一个简单任务开始熟悉命令行的基本用法。这个任务是,在命令行环境里,创建 foo 目录,并在该目录内创建一份 Shell 脚本,令其可在命令行窗口中输出「\type{不怕命令行}」。 \section{Windows 命令行} Windows 用户似乎天生畏惧甚至厌憎命令行环境,甚至很多人认为它是早已被淘汰的上个世纪的东西。这种认识是错误的,原因很简单,最新的 Windows 系统依然不仅依然提供它,甚至处心积虑强化它。 在 Windows 系统中打开命令行窗口,有很多种方法,其中最快的应当是使用如图 \in[win-r] 所示的组合键「Win + R」,打开「运行」对话框,在其中输入「\type{cmd}」,然后点击对话框上的「确定」按钮或单击回车键(Enter 键),便可打开与图 \in[cmd-window] 类似的命令行窗口,只不过你看到的应该是背景为黑色的窗口——我为了打印这一页时能省一些墨,将其改成了白色。 \startplacefigure[location=none] \startfloatcombination[nx=2,ny=1] \startplacefigure[title={Win + R 组合键},reference=win-r] \externalfigure[01/win-r.jpg][height=5.45cm] \stopplacefigure \startplacefigure[title={Windows 命令行窗口},reference=cmd-window] \externalfigure[01/cmd-window.png][height=5.45cm] \stopplacefigure \stopfloatcombination \stopplacefigure 在命令行窗口里,所有要执行的命令皆在「\type{>}」符号后输入,故而该符号叫作{\bf 命令提示符}。需要注意,在输入命令之前,请查看输入法状态,将其切换为英文输入状态。 任何一条命令都是在某个目录下执行的,该目录称为{\bf 工作目录}。命令提示符左侧内容表示文件目录,它就是工作目录。在命令行窗口中输入命令「\type{d:}」,然后单击回车键便可执行该命令,结果是工作目录被切换为 d 盘,倘若它存在。在命令行环境里,输入命令后,必须单击回车键,命令方能得以执行。 假设当前的命令行工作目录为 d 盘,请尝试执行命令「\type{md foo}」,该命令可在 d 盘创建目录 foo。然后执行命令「\type{cd foo}」,将工作目录切换为 foo。现在工作目录就是 \type{d:\foo} 或 \type{D:\foo}——Windows 的命令行语句里,无论是命令还是目录或文件名,不区分大小写。 像 \type{d:\foo} 这样的目录形式称为{\bf 绝对路径},反斜线 \type{\} 称为路径分隔符。有{\bf 相对路径}吗?有。在 \type{d:\foo} 中执行命令「\type{cd ..}」,便可将工作目录切换到上一级,即 d 盘。符号「\type{..}」便是相对路径,表示工作目录的上级目录。 在 \type{d:\foo} 中,若执行命令「\type{cd ..\foo}」,则工作目录不会发生变化,因为 \type{d:\foo} 的上级目录的子目录 foo 依然是 \type{d:\foo}。像「\type{..\foo}」这样的路径也是相对路径。 在 d 盘执行命令「\type{cd ..}」,工作目录会发变化吗?不会。因为 Windows 任何一个盘,其上一级目录为空。 若能理解上述内容,凭借几个简单的命令,便可遨游 Windows 文件系统了,只是我们的任务尚未开始。该任务是在 \type{d:\foo} 中创建一份 Shell 脚本,执行该脚本,在命令行窗口中输出「\type{不怕命令行}」。在 Windows 系统中,Shell 脚本即命令行批处理文件,其扩展名通常为 \type{.bat}。在实现该脚本之前,需要了解 \type{echo} 命令的用法。 \type{echo} 命令亦称回显命令,其功能是读取一些文字,然后将其原样输出。例如, \startmycmd > echo 不怕命令行 不怕命令行 \stopmycmd \noindent 上述代码的第一行是执行「\type{echo}」 命令,第二行是命令的输出结果。 似乎 \type{echo} 是一个什么都不会做的命令,这样的命令有什么用呢?它的一个用途是,通过命令行的输出重定向机制,将一些内容写入制定的文件。例如, \startmycmd d:\foo> echo @echo off > foo.bat \stopmycmd \noindent 上述命令通过输出重定向符「\type{>}」将原本会输出到命令行窗口的文字「\type{@echo off}」输出到文件 \type{d:\foo\foo.bat} c 。倘若该文件事先并不存在,系统会自动创建它。 现在,用 \type{echo} 命令向文件 \type{d:\foo\foo.bat} 的尾部追加一行文字: \startmycmd > echo echo 不怕命令行 >> foo.bat \stopmycmd \noindent 「\type{>>}」也是输出重定向符号,它能够向一份已存在的文件追加内容。在上述代码中,若使用「\type{>}」,则文件原有内容会被新的内容完全替换。 现在,略有纪念意义的时刻到了,这可能是你此生首个甚至也可能是最后一个批处理文件,执行它吧! \startmycmd > .\foo.bat 不怕命令行 \stopmycmd \noindent 上述命令里的「\type{.}」表示工作目录本身,故而「\type{.\foo.bat}」也是一种相对路径,表示工作目录里的 foo.bat 文件。不过,在 Windows 命令行环境里,这种形式的相对路径可以忽略,亦即上述命令可写为 \startmycmd > foo.bat 不怕命令行 \stopmycmd \noindent 在执行某个程序或批处理文件时,倘若未给出其路径,Windows 系统默认先从工作目录中搜索文件,若未搜到,才会在系统环境变量 \type{PATH} 设定的路径中搜索。 系统环境变量 \type{PATH} 是什么呢?既然是变量,必定有值,其值是绝对路径集,以下命令可以查看: \startmycmd > echo %PATH% \stopmycmd \noindent 顺便指出,这是 \type{echo} 命令的另一种用途,即查看环境变量的值。 使用 \type{setx} 命令可以将上述示例创建的批处理文件 foo.bat 所在目录 \type{d:\foo} 追加至 \type{PATH} 变量现有路径集的尾部,如下: \startmycmd > setx /M PATH "%PATH;%d:\foo" \stopmycmd \noindent 务必注意,该命令仅在「以管理员身份」启动的命令行窗口中生效。在 Windows 开始菜单里的搜索栏,输入「\type{cmd}」并单击回车键键提交,然后鼠标右键单击搜索结果,在弹出的菜单中选择「以管理员身份运行」。 验证 \type{d:\foo} 是否被成功添加到系统 \type{PATH} 变量,只需在除 \type{d:\foo} 之外的任一目录验证能否执行 foo.bat,例如 \startmycmd > c: > cd windows\system32 > foo.bat 不怕命令行 \stopmycmd \useURL[Windows 命令行][https://www.bilibili.com/video/BV1vk4y1h7LE/] 若不知如何以管理员身份运行命令行窗口,亦可通过图形界面设置 \type{PATH} 变量。我已将上述构建 \type{d:\foo\foo.bat} 以及如何通过图形界面设置系统 \type{PATH} 变量等过程录制为视频,网络链接为\boxquote{\from[Windows 命令行]},从而避免层峦叠障的 Windows 窗口截图占据本章太多篇幅。 \section{Linux 和 macOS 终端} 在 Linux 系统中,命令行窗口通常称作终端(Terminal),终端里运行的是某种 Shell 程序,它负责执行用户输入的各种命令。 Linux 用户大都知道如何开启终端,甚至我可以放心假设他们已经很熟悉下文所讲的一切了。下面,我以 Bash Shell 为例,写一个脚本,在终端里输出「不怕命令行」。 首先,在终端里进入 \type{$HOME} 目录,亦即 \type{~} 目录,在其中创建子目录 foo: \startmycmd $ cd ~ $ mkdir foo \stopmycmd \noindent 注意,Linux 的命令提示符通常是 \type{$}。 进入 foo 目录,用命令输出重定向,将 \type{echo} 命令的输出结果写入 foo.sh 脚本: \startmycmd $ cd foo $ echo #!/bin/bash > foo.sh $ echo echo 不怕命令行 >> foo.sh \stopmycmd 使用 \type{chmod} 命令为 foo.sh 增加可执行权限,使之能够像程序一样运行: \startmycmd $ chmod +x foo.sh \stopmycmd 以下命令将 \type{~/foo} 添加至系统环境变量 \type{PATH} 并使之在当前终端里生效: \startmycmd $ cd ~ $ echo /BTEX{\Qt'}/ETEXexport PATH=~/foo:$PATH/BTEX{\Qt'}/ETEX >> .bashrc $ source .bashrc \stopmycmd 在任一目录下执行 foo.sh 以验证 \type{~/foo} 是否已被添加至 \type{PATH} 变量,例如 \startmycmd $ cd /tmp $ foo.sh 不怕命令行 \stopmycmd 由于 macOS 和 Linux 皆为 Unix-like(类 Unix)系统,故而二者终端环境的用法近乎相同。如果你知道如何开启 macOS 的终端窗口,则上文所述的 Linux 命令的用法也适于 macOS。不过,macOS 从 Catalina 版开始,默认的 Shell 不再是 Bash,而是 zsh,故而在设置 \type{PATH} 变量时,命令需变更为 \language[en] \startmycmd $ cd ~ $ echo /BTEX{\Qt'}/ETEXexport PATH=~/foo:$PATH/BTEX{\Qt'}/ETEX >> .zshrc $ source .zshrc \stopmycmd 类 Unix 系统里的 Shell 虽然有很多种,但它们的用法颇为相似,而且以 Bash 最为常用。若想对 Bash Shell 有更多的了解,可以阅读我写的一些文章\cite[bash-haters,bash-tutor,ugly-bash]。 \section[installation]{安装 \CONTEXT} 一旦掌握了你所用的操作系统中的命令行基本用法,安装 \CONTEXT\ 就简单多了,下文将分别介绍在 Windows、Linux 以及 macOS 系统入如何安装它。 \useURL[installation][https://wiki.contextgarden.net/Introduction/Installation] \CONTEXT\ 的最新版本是 \CONTEXT\ LMTX,面向 Windows 系统的安装包可从 \boxquote{\from[installation]} 获取,例如 Intel 或 AMD 的 64 位 CPU 架构的 Windows 机器,选择下载 X86 64bits 版本即可。下文以该版本的安装包为例,讲述 \CONTEXT\ LMTX 的安装过程。 \useURL[win-64-version][https://lmtx.pragma-ade.com/install-lmtx/context-win64.zip] 首先,从 \boxquote{\from[win-64-version]} 下载面向 Windows 64 位系统的安装包 \type{context-win64.zip},假设在 \type{d:\} 将其解开,得目录 \type{context-win64},其结构当如图 \in[win64] 所示。完成解包工作,context-win64.zip 包就没用了,可以删除。 \placefigure[force][win64]{\CONTEXT\ LMTX 的 windows 64 位安装包结构}{\externalfigure[01/context-win64.pdf][width=.7\textwidth]} 将 \type{context-win64} 目录改名为 \type{context},然后在命令行窗口依序执行以下命令: \startmycmd > d: > cd context > install.bat > setpath.bat > mtxrun --generate \stopmycmd 上述命令里,批处理文件 install.bat 可从网络上下载 \CONTEXT\ LMTX 的所有文件,存放在工作目录。安装时长取决于网络下载速度。\CONTEXT\ LMTX 的服务器在境外,由于国内众所周知的原因,导致文件下载速度可能会非常缓慢,而且安装过程甚至可能中断,需要你多次执行 install.bat 文件,方能完成整个安装过程。幸好 install.bat 是增量安装,即使有所中断,每次它会从中断处开始安装,而非从头重新安装。后文会给出符合国情的快捷方案。 从现在开始,称 \type{d:\context} 目录为 {\bf\CONTEXT\ 安装目录}。若想验证 \CONTEXT\ LMTX 是否安装完全,可在 \CONTEXT\ 安装目录执行以下命令: \startmycmd > setpath.bat > md test > cd test > echo \startTEXpage[frame=on,offset=1pt] > foo.tex > echo Hello \CONTEXT! >> foo.tex > echo \stopTEXpage >> foo.tex > context foo.tex \stopmycmd \noindent 倘若在 \type{d:\context\test} 目录下能够得到 \type{foo.pdf} 文件,且其内容为 \lower.3em\hbox{\externalfigure[01/foo.pdf]},则意味着已成功安装 \CONTEXT\ LMTX。 最后一步,将 \type{d:\context\tex\texmf-win64\bin} 添加到系统 \type{PATH} 变量,便可在任一目录使用 \type{context} 命令将扩展名为 \type{.tex} 的文本文件编译为同名的 PDF 文件。 \useURL[sumatra][https://www.sumatrapdfreader.org/free-pdf-reader] 上述命令创建的 foo.tex 文件,你可以用任何一款文本编辑器打开,作一些编辑,例如用 Windows 的记事本程序打开它: \startmycmd > notepad foo.tex \stopmycmd 如果你没有 PDF 阅读器,或者每次重新编译 \type{.tex} 文件时,你的 PDF 阅读器没有自动更新显示 PDF 文件的内容,我建议你用 Sumatra PDF 阅读器,其下载页面位于\boxquote{\from[sumatra]}。 假设你的 Linux 是 Inter 或 AMD 架构的 64 位系统,并且你希望将 \CONTEXT\ LMTX 安装在 \type{~/opt} 目录,亦即 \type{~/opt},则整个安装过程可表述为以下 Bash 命令: \startmycmd $ mkdir -p ~/opt/context $ cd ~/opt/context $ wget https://lmtx.pragma-ade.com/install-lmtx/context-linux-64.zip $ unzip context-linux-64.zip $ sh install.sh $ echo /BTEX{\Qt'}/ETEXexport PATH=~/opt/context/tex/texmf-linux-64/bin:$PATH/BTEX{\Qt'}/ETEX >> ~/.bashrc $ mtxrun --generate $ rm context-linux-64.zip \stopmycmd 在 macOS 系统中安装 \CONTEXT\ LMTX 所用命令与上述 Linux 系统安装命令近乎相同,只是 macOS 环境里默认可能没有 \type{wget} 命令,不过你可以用 \type{curl} 命令替代它。以下命令可获得面向 macOS 64 位系统的 \CONTEXT\ LMTX 安装包: \startmycmd $ curl -O https://lmtx.pragma-ade.com/install-lmtx/context-osx-64.zip \stopmycmd 在安装过程结束后,你可能需要消除一些文件的隔离标记。假设你的 \CONTEXT\ 安装目录为 \type{~/opt/context},可执行以下命令完成该工作。 \startmycmd $ sudo xattr -r -d com.apple.quarantine ~/opt/context/bin/mtxrun $ sudo xattr -r -d com.apple.quarantine ~/opt/context/tex/texmf-osx-64/bin/* \stopmycmd \section{接力式安装} \useURL[installation][https://wiki.contextgarden.net/Introduction/Installation] 上述安装方法源于\boxquote{\switchtobodyfont[9pt]\from[installation]},其中面向 Windows 和 Linux 的安装过程,我皆已实践,除文件下载速度太慢以及安装过程偶有中断之外,没有其他问题。面向 macOS 系统的安装过程,我没有条件予以验证,只能纸上谈兵。 为了加快安装进程,我将 Windows 和 Linux 里装好的 \CONTEXT\ LMTX 分别打包,以时间为后缀,上传到了网盘。你可以下载它们,只需将其解包到指定目录,便可拥有一个版本略微落后的 \CONTEXT\ LMTX 环境。之后只需执行安装目录里的 install 脚本便可追及最新版本——相当于意外中断后继续安装。由于这部分内容经常变化,而本文档更新周期通常以年为单位,故而我将其做成一个网页: \useURL[my-shoulder][https://zhuanlan.zhihu.com/p/1943204598711054617] \midaligned{\boxquote{\from[my-shoulder]}}。 \noindent 只需按照该网页的说明,便可创建一个纯净的 \CONTEXT\ LMTX 环境。 \section[ctx-in-texlive]{\TEX\ Live 中的 \CONTEXT} \TEX\ Live 是迄今为止最为权威的 \TeX\ 系统,\LaTeX\ 用户大多使用该系统,不过该系统也收录了 \CONTEXT\ 包。相比于 \CONTEXT,\TEX\ Live 是更为宏大的 \TeX\ 体系,前者可谓是后者的一颗行星。由于 \TEX\ Live 提供了图形界面的安装程序,如果你始终都不得命令行其门而入,可以考虑用该程序安装 \CONTEXT\ LMTX。 鉴于本章的主题是在命令行环境里安装 \CONTEXT,倘若在此讲述 \TEX\ Live 系统的图形化安装过程,结果必定会喧宾夺主,仅是安装过程的一些截图所占的篇幅就已经超过了前文所有内容。不过,为了让你能多一条路,该安装方式在上一节的 \CONTEXT\ 接力棒的在线文档中里也有记述,并且以视频的形式演示了安装过程。 \subject{结语} 也许你已经学会了如何在命令行环境里安装 \CONTEXT,但我更希望你能熟悉甚至习惯以命令行的方式工作。著名的开源运动先驱者 Eric Raymond 在其《Unix 编程艺术》一书的附录部分写了一些禅宗式的寓言,其中有一则与图形界面程序有关。在这则寓言里,一个程序员对 Unix 领域的一个智者说,现代的,设计得当的操作系统可以在图形用户界面里做任何事情。智者没说话,只是用手指了一下月亮,旁边有条狗冲着智者的手狂吠。程序员不解其意。智者陆续又指了佛像、窗户、程序员的脑袋和路边的石头,程序员依然不解。智者只好轻拍程序员鼻子两下,将其扔到旁边的垃圾桶中。当程序员试图从垃圾桶中爬出来时,狗跑过来,在他身上撒尿。此刻程序员终于悟出,图形界面的问题在于难以用语言与他人交流软件的用法。