技术干货:Shell命令、troff宽度表及mm与ms宏包对比全解析
1. Shell命令总结
Shell命令在系统操作中扮演着至关重要的角色,下面将详细介绍Bourne Shell的语法,涵盖特殊字符、变量以及内置编程命令。
1.1 特殊文件
-
$HOME/.profile:在Shell启动时执行。
1.2 文件名生成的特殊字符
| 字符 | 功能 |
|---|---|
*
| 匹配任意字符串 |
?
| 匹配任意单个字符 |
[ ... ]
| 匹配方括号内的任意字符,若两个字符用连字符分隔,则匹配这两个字符之间的任意字符 |
1.3 控制流特殊字符
| 字符 | 功能 | 示例 |
|---|---|---|
|
| 执行管道操作,将前一个命令的输出作为后一个命令的输入 |
cat file | lpr
|
;
| 分隔同一行的顺序命令 | |
&
| 在后台运行命令 |
lpr file &
|
&&
| 若前一个命令执行成功,则执行后续命令 |
grep string file && lpr file
|
||
| 若前一个命令执行失败,则执行后续命令 |
grep string1 file || grep string2 file
|
1.4 变量替换
| 表达式 | 功能 |
|---|---|
variable=value
| 将变量设置为指定值 |
$variable
| 使用变量的值 |
${variable:-value}
| 若变量已设置,则使用该变量;否则将其设置为指定值 |
${variable:?value}
| 若变量已设置,则使用该变量;否则打印指定值并退出 |
1.5 Shell参数和变量
| 参数/变量 | 功能 |
|---|---|
$#
| 命令行参数的数量 |
$-
|
调用时或通过
set
命令提供的选项
|
$?
| 最后执行命令的返回值 |
$$
| 当前进程的进程号 |
$!
| 最后一个后台命令的进程号 |
$HOME
|
cd
命令的默认(主目录)值
|
$IFS
| 内部字段分隔符 |
$MAIL
| 默认邮件文件 |
$PATH
| 命令的默认搜索路径 |
$PS1
|
主提示符字符串,默认为
$
|
$PS2
|
次提示符字符串,默认为
>
|
$TERM
| 指定终端类型 |
1.6 Shell函数和内置命令
- Shell函数 :
name() { command1; ...; commandn }
创建一个名为
name
的函数,该函数由花括号内的命令组成,可在当前脚本中通过名称调用。
-
内置命令
:
| 命令 | 功能 |
| ---- | ---- |
|break [n]| 从for、while或until循环中退出n层 |
|case| 根据模式匹配执行相应命令 |
|cd [dir]| 更改当前目录为指定目录 |
|continue [n]| 继续for、while或until循环的第n次迭代 |
|echo args| 在标准输出上打印参数 |
|eval [arg ...]| 计算参数,然后执行结果 |
|exec [cmd]| 用指定命令替换当前Shell |
|exit [n]| 以指定状态码退出Shell |
|export [var ...]| 将变量导出到环境中 |
|for variable [in list ...]| 对列表中的每个项执行命令 |
|if| 根据条件执行相应命令 |
|hash cmds| 临时将命令添加到搜索路径中 |
|login [user ...]| 以其他用户身份登录 |
|newgrp [group ...]| 更改组ID |
|pwd| 打印当前工作目录 |
|read [var ...]| 从标准输入读取变量的值 |
|readonly [var ...]| 将变量标记为只读 |
|return| 停止当前Shell函数的执行并返回调用级别 |
|set [t] [options]| 设置或显示Shell变量和选项 |
|shift| 对参数进行移位操作 |
|test exp或[exp]| 计算表达式的值 |
|times| 打印累积的进程时间 |
|trap [cmd] [n]| 当接收到指定信号时执行命令 |
|type commands| 打印命令的相关信息 |
|until condition| 直到条件满足为止,执行命令 |
|ulimit [size]| 设置可创建文件的最大大小 |
|umask [nnn]| 设置文件创建掩码 |
|unset vars ...| 删除变量的定义 |
|wait [n]| 等待指定进程终止并报告其状态 |
|while condition| 当条件满足时,执行命令 |
|filename| 读取并执行可执行文件中的命令 |
2. troff宽度表格式
troff使用存储在
/usr/lib/font
目录中的宽度表来确定如何在页面上放置文本,下面将详细介绍其相关内容。
2.1 目录结构
对于系统支持的每种troff输出设备,都有一个名为
/usr/lib/font/devX
的目录,其中
X
是设备名称。例如:
$ ls -F /usr/lib/font
devlj/
devps/
每个目录中包含一个总体设备描述文件
DESC
和系统字体的各个字体文件,这些文件有ASCII和二进制两种形式,二进制文件通过
makedev
实用程序从ASCII版本创建,后缀为
-out
。
2.2 DESC文件
DESC文件包含输出设备的总体描述,包括分辨率、纸张大小、默认安装的字体、可用的字号以及设备支持的所有troff特殊字符名称的完整列表。示例如下:
# HP LaserJet
fonts 6 R I B HB CW S
sizes 7 8 10 12 14 17 22 27 0
res 300
hor 1
vert 1
unitwidth 12
paperwidth 2400
paperlength 3300
charset
fi fl ff Fi F1
br vr ul ru
bu sq em hy 14 12 34 aa ga
\I
\A
\-
sc gr no is pt es mo
dd rh lh bs or ci
It lb rt rb lk rk bv If rf IC rc
DESC文件中使用的关键字及其功能如下:
| 关键字 | 功能 |
| ---- | ---- |
|
fonts
| 指定设备要安装的字体数量,后跟字体名称列表(最多十个) |
|
sizes
| 各种字体可用的字号 |
|
res
| 输出设备的分辨率,以每英寸点数为单位 |
|
hor
| 设备在水平方向上可移动的最小分辨率单位数 |
|
vert
| 设备在垂直方向上可移动的最小分辨率单位数 |
|
unitwidth
| 其他文件中指定字符宽度的字号 |
|
paperwidth
| 页面的宽度,以分辨率单位为单位 |
|
paperlength
| 页面的长度,以分辨率单位为单位 |
|
biggest font
| 字体中字符的最大数量 |
|
charset
| 该输出设备支持的字符名称列表 |
|
#
| 开始注释 |
2.3 字体描述文件
对于DESC文件中
fonts
行列出的每个字体,都应有一个同名的字体文件,该文件包含字体中所有字符的列表,以及字符的宽度和其他相关信息。示例如下:
name R
internalname Roman
charset
4
8
VII
0
ru
25
A
42
B
35
C
37
W
40
X
28
Y
28
z
25
0
0
3
0
2
65
2
66
2
67
0
119
0
120
1
121
0
122
0
0
13
17
每个字符列出四列,用制表符分隔:
1.
字符名称
:可以是字母、数字、符号或DESC文件
charset
部分定义的双字符troff特殊字符名称。
2.
字符宽度
:以输出设备单位表示的字符宽度,该宽度是在DESC文件中
unitwidth
关键字指定的字号下的宽度。
3.
字符类型
:表示字符是下降符(1)、上升符(2)、两者皆是(3)还是都不是(0)。
4.
排版代码
:输出设备用于生成字符的代码,可以是十进制或八进制形式。
2.4 字体文件编译
完成宽度表后,需要使用
makedev
实用程序进行编译:
$ makedev DESC # 编译DESC文件中列出的所有字体
$ makedev B # 编译未包含在DESC文件中的字体
2.5 字体使用限制
用户不限于使用DESC文件中列出的“安装”字体,任何输出设备支持且有编译宽度表的字体都可以在文档中引用。但有时会遇到问题,如果使用的字体文件大小大于DESC文件中指定的最大安装字体,则troff可能会出现问题。解决方法包括:
- 从字体中删除不需要的字符。
- 在DESC文件中填充字体。
- 将有问题的大字体添加到DESC文件中。
3. 对比mm和ms宏包
如果系统中同时存在
ms
和
mm
宏包,可能会对它们的功能进行评估。一般来说,
ms
和
mm
有许多相同的功能,但
ms
缺少一些重要功能,如自动编号列表和目录生成。不过,
ms
的内部机制更容易学习,因此更容易用自定义宏进行扩展。
3.1 段落
| 宏包 | 块段落 | 首行缩进段落 |
|---|---|---|
ms
|
.P
|
.P1
|
mm
|
.LP
|
.PP
|
在
mm
中,可以通过将数字寄存器
Pt
设置为1或2来将默认段落类型从块段落更改为缩进段落,而
ms
宏缺少这种通用机制。
|
3.2 对齐方式
-
mm
:使用
nroff格式化程序时,mm不右对齐文本。.SA 1可开启两个格式化程序的对齐功能,.SA 0则关闭。 -
ms
:
ms宏没有用于抑制段落正常对齐的宏,但可以使用.na请求来实现。
3.3 显示
两个宏包都使用
DS/DE
宏对来生成显示内容,但在对齐方式上有所不同:
-
mm
:显示内容左对齐,提供静态和浮动显示(
.DF
),可以在显示内容中开启填充模式并指定右边界缩进。
-
ms
:显示内容缩进,使用单独的保留宏对(
KS/KF
和
KE
)实现类似功能,
QP
或
QS/QE
对可实现类似的引用材料功能。
3.4 列表格式化
- mm :具有复杂的列表格式化宏。
-
ms
:
.IP宏可生成类似于mm中的可变项列表,但无法生成自动编号列表。
3.5 字体更改
两个宏包都使用
.B
(更改为粗体)、
.I
(更改为斜体)和
.R
(更改为罗马字体)宏来更改字体,但
mm
宏允许最多七个参数用于与前一个字体交替,而
ms
仅限于两个。
3.6 字号更改
| 宏包 | 功能 | 宏 |
|---|---|---|
mm
| 指定新字号 |
.S
|
mm
| 相对于当前字号减小字号 |
.SM
|
ms
| 相对于当前字号增加或减小2点 |
.LG
和
.SM
|
ms
| 恢复默认字号 |
.NL
|
3.7 页眉和页脚
-
mm
:提供用于指定在页面页眉或页脚中左对齐、居中对齐和右对齐的分隔字符串的宏,
.PH定义页眉,.PF定义页脚,还提供用于指定奇数页和偶数页页眉和页脚的变体宏。 -
ms
:通过设置单个字符串来处理页眉和页脚,例如使用
.ds LH string定义页眉中左对齐的字符串。
3.8 章节标题
| 宏包 | 编号章节标题 | 无编号章节标题 |
|---|---|---|
ms
|
.SH
|
.NH
|
mm
|
.H
|
.HU
|
主要区别在于指定标题字符串的位置,
mm
中是宏所在行的第一个参数,而
ms
中是宏所在行的下一行,直到第一个段落宏。
|
3.9 脚注
两个宏包都使用
.FS
和
.FE
宏对来处理脚注,但
mm
提供了脚注的自动编号功能,且页面底部的脚注以8点字体打印。此外,
mm
还提供了
.RF
和
.RE
宏对用于收集参考页面。
综上所述,
mm
和
ms
宏包各有优缺点,用户可以根据具体需求选择合适的宏包。在实际使用中,还可以结合它们的特点,灵活运用以满足不同的文档排版需求。
3. 对比mm和ms宏包(续)
3.10 功能对比总结
为了更清晰地展示
mm
和
ms
宏包的功能差异,我们可以通过以下表格进行总结:
| 功能 | mm宏包 | ms宏包 |
|---|---|---|
| 段落类型设置 |
可通过设置寄存器
Pt
改变默认段落类型
| 缺乏通用的段落类型设置机制 |
| 对齐方式控制 |
可通过
.SA
宏控制对齐
|
用
.na
请求抑制对齐
|
| 显示内容处理 | 左对齐,有静态和浮动显示,可设置填充和缩进 | 缩进显示,用保留宏对实现类似功能 |
| 列表格式化 | 有复杂的列表格式化宏,可自动编号 | 只能生成可变项列表,无自动编号功能 |
| 字体更改 | 允许最多七个参数与前字体交替 | 仅限于两个参数 |
| 字号更改 | 可指定新字号或相对减小字号 | 相对当前字号增减2点或恢复默认字号 |
| 页眉页脚设置 | 提供多种设置宏,区分奇偶页 | 需设置单个字符串 |
| 章节标题指定 | 标题字符串在宏所在行第一个参数 | 标题字符串在宏所在行下一行 |
| 脚注处理 | 自动编号,8点字体打印,有参考收集宏 | 无自动编号和参考收集功能 |
通过这个表格,我们可以直观地看到两个宏包在不同功能上的差异,从而根据实际需求进行选择。
3.2 选择建议
下面通过一个mermaid流程图来展示如何根据需求选择合适的宏包:
graph TD;
A[是否需要自动编号功能?] -->|是| B[选择mm宏包];
A -->|否| C[是否需要简单易扩展的宏包?];
C -->|是| D[选择ms宏包];
C -->|否| E[根据其他需求进一步比较];
如果用户需要自动编号列表、目录生成、脚注自动编号等功能,那么
mm
宏包是更好的选择。例如,在撰写长篇文档时,自动编号功能可以大大提高效率。
如果用户更注重宏包内部机制的易学习性和扩展性,希望能够方便地添加自定义宏,那么
ms
宏包会更合适。比如,在进行一些个性化的文档排版时,
ms
宏包的可扩展性就会发挥优势。
4. 综合应用场景分析
4.1 系统管理场景
在系统管理中,Shell命令是必不可少的工具。系统管理员可以使用各种Shell命令来完成日常的任务,如文件管理、进程控制等。例如:
- 使用
cd
命令切换工作目录,方便对不同目录下的文件进行操作。
cd /var/log
-
使用
ls命令查看目录中的文件和子目录。
ls -l
-
使用
grep命令在文件中查找特定的字符串。
grep "error" log.txt
同时,了解troff宽度表的格式对于生成高质量的系统文档也非常有帮助。管理员可以根据系统输出设备的特点,调整宽度表,确保文档的排版符合要求。
4.2 文档撰写场景
在文档撰写方面,
mm
和
ms
宏包的选择取决于文档的具体需求。如果是撰写学术论文、报告等需要自动编号列表和目录的文档,建议使用
mm
宏包。以下是一个使用
mm
宏包生成自动编号列表的示例:
.IP 1.
这是第一个列表项。
.IP 2.
这是第二个列表项。
如果是撰写一些简单的技术笔记、备忘录等,
ms
宏包的简单性和可扩展性就会更有优势。例如,用户可以自定义宏来满足特定的排版需求。
4.3 脚本编程场景
在脚本编程中,Shell函数和内置命令可以帮助用户实现自动化任务。例如,使用
for
循环遍历文件列表:
for file in $(ls *.txt); do
echo $file
done
使用
if
语句进行条件判断:
if [ -f file.txt ]; then
echo "文件存在"
else
echo "文件不存在"
fi
5. 总结与展望
通过对Shell命令、troff宽度表以及
mm
和
ms
宏包的详细介绍和对比,我们可以看到这些技术在不同场景下都有着重要的应用价值。
在未来的技术发展中,我们可以期待这些工具和技术不断完善和优化。例如,Shell命令可能会增加更多的功能和选项,以满足更复杂的系统管理需求;troff宽度表的生成和调整可能会更加自动化和智能化;
mm
和
ms
宏包也可能会融合彼此的优点,提供更强大、更易用的文档排版功能。
对于技术人员来说,深入学习和掌握这些技术,能够提高工作效率,提升文档质量,为系统管理和文档撰写带来更多的便利。同时,不断关注技术的发展动态,积极尝试新的功能和特性,也有助于保持技术竞争力。
超级会员免费看
307

被折叠的 条评论
为什么被折叠?



