\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 领域的一个智者说，现代的，设计得当的操作系统可以在图形用户界面里做任何事情。智者没说话，只是用手指了一下月亮，旁边有条狗冲着智者的手狂吠。程序员不解其意。智者陆续又指了佛像、窗户、程序员的脑袋和路边的石头，程序员依然不解。智者只好轻拍程序员鼻子两下，将其扔到旁边的垃圾桶中。当程序员试图从垃圾桶中爬出来时，狗跑过来，在他身上撒尿。此刻程序员终于悟出，图形界面的问题在于难以用语言与他人交流软件的用法。
