笔记-UnixLinux大学教程

Unix键盘使用

在键盘上,按下<Return>键或^M键(它们等价)可以发送一个CR码。按下<Linefeed>或者^J键可以发送一个LF码。CR为返回信号,LF码为换行信号。

修饰键:<Ctrl>键

erase kill werase rprnt flush lnext
^H ^U ^W ^R ^O ^V
susp intr quit stop eof
^Z/^Y ^C ^\ ^S/^Q ^D

erase删除最后一个键入的字符,werase删除最后一个键入的单词,而kill则删除整行。

元字符

字符 名称 作用
{} 花括号 花括号扩展:生成一种字符模式
| 管道 命令行:创建一个管道线
< 小于 命令行:重定向输入
> 大于 命令行:重定向输出
() 圆括号 命令行:在子shell中运行命令
# hash、pound 命令行:注释的开头,忽略该行的其余部分
; 分号 命令行:用于分隔多条命令
` 反引号 命令行:命令替换
~ 波浪号 文件名扩展:插入home目录的名称
? 问号 文件名扩展:匹配任意一个字符
[] 方括号 文件名扩展:与一组字符中的字符匹配
* 星号 文件名扩展:匹配0个或多个字符
! bang 历史列表:事件标记
& 和号 作业控制:在后台运行命令
\ 反斜线 引用:下一个字符转义
引号、单引号 引用:取消所有的替换
双引号 引用:取消大部分替换
{} 花括号 变量:确定变量名称的界限
$ 美元符号 变量:用变量的值替换
<Return> 新行字符 空白符:标记一行结束
<Tab> 制表符 空白符:在命令行中分隔单词
<Space> 空格符 空白符:在命令行中分隔单词

有时候,可能希望按字面上的含义使用元字符,而不使用其特殊的含义。例如,将分号作为分号使用,而不是一个命令分隔符。或者可能希望不按管道使用|(竖线)。在这些情况中,必须告诉shell按字面意义解释字符。这样做时,可以称其为引用字符。

字符的引用方法有三种:使用反斜线、使用一对单引号或者使用一对双引号。

引用元字符最直接的方法就是在元字符前面放一个反斜线(\)。这就告诉shell忽略反斜线之后的字符的任何特殊含义。例如:

1
echo It is warm and sunny\; come over and visit

在这个例子中,我们在分号前放了一个反斜线。如果没有这个反斜线,那么shell将把这个分号解释成一个元字符,从而假定了您输入了两条独立的命令:echo和come。

考虑下述指令:

1
echo It is warm (and sunny); come & visit

这条命令不能正确运行,因为命令中有四个元字符。我们当然可以用四个反斜线依次引用每个元字符,但这样得到的命令却不容易阅读,一个更好的方法是使用单引号引用一串字符:

1
echo 'It is warm (and sunny); come & visit'

在这个例子中,我们将单引号之间的所有内容引用。当然,这包括所有的字符,而不仅仅是元字符,但是它不影响数字字母字符的显示。

大多数时候,反斜线和单引号引用已足够。但是,在有些情形中,使用双引号引用更加方便。有时候,可能希望在一个引用字符串中使用$字符,用来引用变量的值,例如,下述命令在尖括号中显示用户标识和终端类型:

1
echo My userid is <$USER>; my terminal is <$TERM>

这种形式的命令不能正常工作,因为元字符<、;和>拥有特殊的含义($字符没有什么问题,我们希望它是元字符)。解决方法就是只引用那些我们希望取字面含义的元字符:

1
echo My userid is \<$USER\>\; my terminal is \<$TERM\>

这条命令可行,但是它非常复杂。而如果使用单引号来取代反斜线:

1
echo 'My userid is <$USER>; my terminal is <$TERM>'

这样比较容易阅读,但它引用了所有的元字符,包括$。这意味着只能看到字面上的$USER和$TERM,而不能看到这两个变量的值。对于这种情况,可以使用双引号,因为这样所有的$元字符将保留它们特殊的含义。例如:

1
echo "My userid is <$USER>; my terminal is <$TERM>"

下面是小结:

使用反引号引用单个字符(称为转义了这个字符)。

使用单引号引用一串字符。

使用双引号引用一串字符。但是保留$(美元)、`(反引号)和\(反斜线)的特殊含义。

从前面的讨论中可以看出,单引号比双引号的功能更为强大。基于这一原因,有时候称单引号为强引用strong quote,双引号为弱引用weak quote。实际上,反斜线是所有引用中最强的一个。反斜线可以引用任何东西,因此,如果单引号不起作用,可以试一试反斜线。例如,有一天您可能需要转义一个单引号:

1
echo Don\' t let gravity get you down

反斜线功能如此强大,所以它甚至可以引用新行字符(花点时间好好想想这一点)。

假设在某行的末尾键入了\<Return>,这样将生成\字符后面跟新行字符。光标移动到下一行,但是由于新行字符失去了它特殊的含义,所以它并不是一行结束的信号。这意味着不管接下来键入什么字符都是上一行的继续。

1
2
3
echo Tis is a very, very long \
line that goes on and on for a \
very, very long time.

命令

以超级用户工作:su

su(substitute userid)命令允许您临时变成另一个用户标识。为此,只需在su命令后输入新的用户标识即可。

1
2
3
[harley]$ su weedly
Password:
[weedly]$

当您结束weedly的工作时,您需要做的就是结束当前shell。输入exit命令就可以结束当前shell。一旦结束了新shell,您就会自动返回原来的shell,即用户标识harley。

1
2
[weedly]$ exit
[harley]$

上述例子中,您将用户标识变成weedly,但是仍然在harley的环境下工作。如果希望同时变换用户标识和环境,则需要在su命令名称之后键入一个-(连字符)。注意,连字符的两边都有一个空格。

1
su - weedly

现在您在weedly的环境中以weedly的名义工作了。

为方便起见,如果su命令没有指定用户标识,那么默认的用户标识是root。因此,下述两个命令是等效的。

1
2
su -
su - root

以超级用户执行一条单独的指令:sudo

切换至超级用户的时间太长会非常危险,sudo(substitute the userid an do something)命令允许您以另一个用户标识执行一条单独的命令。和su命令一样,sudo命令的默认用户标识为root。因此,为了以超级用户执行一条具体的命令,只需:

1
sudo command

键映射:stty

显示系统的键盘映射时,使用下述命令:

1
stty -a

stty是“set terminal”命令,-a意味着“显示所有的设置”。

信号 作用
erase Backspack / Delete 删除键入的最后一个字符
werase ^W 删除键入的最后一个单词
kill ^X/^U 删除整行
intr ^C 停止正在运行的程序
quit ^\ 停止程序并保存core文件
start ^Q 重新启动屏幕显示
eof ^D 指示已经没有数据

如果希望修改键映射,只需键入stty,后面跟着信号的名称,然后是新的键赋值即可。例如,将kill键修改为^U的命令如下:

1
stty kill ^U

当在stty命令中使用带Ctrl的字符名时,不必键入大写字母。例如,下面两条命令都能正常工作:

1
2
stty kill ^u
stty kill ^U

在系统中查找程序:which、type、whence

查找某个程序是否可用的一种精确方法就是使用which命令,只需在键入的which命令后跟一个或多个程序的名称即可,例如:

1
which date less vi harley

我的机器运行以上指令的输出为:

1
2
3
/usr/bin/date
/usr/bin/less
/usr/bin/vi

which没有找到名为harley的程序,因此没有任何输出

如果您使用的shell是Bash,那么which命令还有一个备用指令type,例如:

1
type date

如果使用的是Korn shell,那么您可以使用whence命令:

1
whence date

type和whence命令有时候要比which命令显示更多的细节信息。这在特定的环境下很有用。但是,在实机应用上,还是which命令的应用最广泛。

显示时间和日期:date

简单的输入:

1
date

Unix将显示当前的时间和日期。下面是一个样本输出,注意Unix使用的是24小时制时钟。

1
Fri Dec 24 23:35:06 CST 2021

从本质上讲,Unix并没有运行在本地时间上。所有的Unix系统都使用协调世界时Coordinated Universal Time, UTC,它是格林威治标准时间Greenwich Mean Time, GMT的现代名称。Unix在需要时默默地在UTC和本地时区之间进行转换。本地时区的细节信息在安装Unix时指定。

有时候,查看UTC时间比较便利。为了显示UTC时间,只需使用:

1
date -u

显示日历:cal

显示当前月份的日历时,可以输入:

1
cal

显示某一年的日历时,需要指定年度。例如:

1
cal 1949

为了显示某个特点月份的日历,需要先指定月份,再指定年度。例如,显示1952年12月的日历的命令如下:

1
cal 12 1952

如果输入的是:

1
cal 12

那么得到的是公元12年的日历。

如果不希望显示日期,只希望得到这一天是这一年中的第几天,只需在cal名称之后键入-j即可。

1
2
3
4
5
6
7
8
	cal -j 12 2009
December 2009
Su Mo Tu We Th Fr Sa
335 336 337 338 339
340 341 342 343 344 345 346
347 348 349 350 351 352 353
354 355 356 357 358 359 360
361 362 363 364 365

查看系统信息:uptime、hostname、uname

uptime用来显示系统已经运行多长时间(也就是连续运行)的有关信息:

1
uptime

一些典型的输出:

1
2
11:10AM up 103 days, 6:13, 3 users,
load averages: 1.90, 1.49, 1.38

在这个例子中,系统已经运行了103天6小时13分钟,而且当前有3个用户标识登录。最后三个数字展现了一直等待执行的程序的数量,分别是之前1分钟、5分钟和15分钟的平均数。这些数字表示系统的负载。负载越高,系统所做的工作就越多。

hostname命令用来查看计算机的名称。如果经常登录不止一台计算机,那么该命令非常管用。如果忘记了正在使用的是哪一个系统,则可以输入:

1
hostname

uname命令显示操作系统的名称。

显示自己的信息:whoami

whoami命令显示您登录使用的用户标识。如果您突然得了健忘症,忘记了自己的名字,那么whoami命令也许特别有用。如果您的系统上没有whoami命令,则可以尝试输入下面3个单独的单词:

1
who am i

请求Unix提醒何时离开:leave

在计算机上工作时经常需要全神贯注,很容易忘记时间。为了帮助您及时完成其他事情,只需输入下述命令:

1
leave

leave将询问您一个时间:

1
When do you have to leave?

hhmm(先是小时,后是分钟)的格式输入您希望离开的时间。例如希望在10:33离开,可以输入1033。

时间输入既可以是12小时制也可以是24小时制。例如,1344意味着1:44PM。而如果输入的小时数小于等于12,那么leave假定时间位于接下来12小时内。例如,如果现在时间是8:00PM,而您输入的是855,那么leave将它解释为8:55PM,而不是8:55AM。

如果需要在特定的时间间隔之后离开,则可以输入一个+(加号),后面跟着分钟数。例如,如果需要在15分钟之后离开,可以输入:

1
leave +15

确保不要在+字符之后留空格。

内置计算器:bc

如果您希望使用bc内置的数学函数库,那么在启动程序时需要使用-l(library)选项:

1
bc -l

不希望使用bc时,可以通过按^D或输入quit命令。

函数 含义
sqrt(x) x的平方根
s(x) x的正弦:其中x的单位是弧度
c(x) x的余弦:其中x的单位是弧度
a(x) x的反正切:其中x的单位是弧度
ln(x) x的自然对数
j(n, x) x的n次整阶贝塞尔函数

默认情况下,bc假定做整数运算。您可以设置一个标度因子,告诉bc您希望保留小数点后几位。例如,要保留小数点后面3位,可以输入:

1
scale=3

如果希望查看标度因子的值,只需简单输入:

1
scale

bc允许设置并使用变量。变量由变量名和值组成。在bc中,变量名由一个小写字母构成。也就是说,bc中共有26个变量,从a到z(一定确保不要使用大写字母,当使用基时才使用它们——参见下面)。

您可以使用等号设置变量的值。例如,将变量x的值设置为100,可以输入:

1
x=100

显示变量的值,只需输入变量名,例如:

1
x

默认情况下,在变量没有赋值之前,bc假定所有变量的值为0。

一般情况下,bc计算时使用10作为基。但是,有时候您可能需要使用另一种基进行计算。bc允许对输入和输出指定不同的基。具体操作时,需要设置两个特殊的变量:ibase是用于输入的基;obase是用于输出的基。

例如,如果希望以基16显示答案,可以输入:

1
obase=16

如果希望以基8输入数字,则需要使用:

1
ibase=8

对于大于或等于10的基值,bc分别使用大写字母A、B、C、D、E、F表示值10、11、12、13、14和15.记住一定要使用大写字母,如果使用了小写字母,那么bc将会认为它是变量,从而使结果出错。

为方便起见,无论设置的输入基是什么,都可以使用这些大写字母。例如,即使现在使用的基是10,表达式A+1的值也是11。

和其他变量一样,直接输入ibase和obase自身就可以获得它们的当前值:

1
ibase; obase

但是,一定要小心。因为一旦设置了obase的值,所有的输出都将以这个基进行显示,显示的值可能会对您产生麻烦。例如,如果您输入:

1
2
obase=16
obase

那么您将看到:

1
10

这是因为此时所有的输出都以基16显示,而在基16中,值“16”就表示为10。

同理,一旦修改了ibase,在输入时也必须特别小心。例如,假设您设置了:

1
ibase=16

现在希望将obase设置为基10,因此您输入:

1
obase=10

但是,您忘了现在的输入基是16,而10在基16中其实是“16”。因此,obase还是被设置成基16。

为了避免出现这样的错误,可以使用字母A到F,无论ibase的值是多少,它们仍然是原来的值。因此,如果事情出现了混乱,您总可以这样重新设置基:

1
obase=A; ibase=A

什么是Unix手册?man

下面准备讨论的命令是针对less分页程序的,因为大多数Unix系统使用它。如果man命令使用的是more或者pg,那么为了获得该特定分页程序的帮助摘要信息,您也只需按下h键。

通用命令
q 退出
h 显示帮助信息
阅读说明书页
<Sapce> 显示下一屏
<PageDown> 显示下一屏
f 显示下一屏
<PageUp> 显示上一屏
b 显示上一屏
搜索
/pattern 向下搜索特定的模式
?pattern 向上搜索特定的模式
/ 向下搜索上一模式
n 向下搜索上一模式
? 向上搜索上一模式
N 向上搜索上一模式
在说明书页中移动
<Return> 向下移一行
<Down> 向下移一行
<Up> 向上移一行
g(go to top) 移到页的顶部
G(go to bottom) 移到页的底部

当阅读说明书页时,如果您键入一个!(感叹号),就可以在它之后键入一条shell命令。man程序将把这条命令发送给shell,而shell将运行这个命令。当命令结束后,可以按下<Return>键返回到man程序中。

一种快速查询命令作用的方法:whatis

当输入man命令时,Unix将显示整个手册页。但有时候,您可能只对一个简要描述感兴趣。在这种情况下,还有另外一种方法。

说明书页的Name节中包含一行描述。如果只想看这一行内容,可以键入man -f,后面跟一个或者多个命令的名称。例如:

1
man -f time date

在man命令的这种形式中,-f称为一个选项,代表单词“files”。每个说明书页都存储在一个单独的文件中。当使用-f选项时,就是告诉man查找哪些文件。

为了方便起见,可以使用命令whatis来取代man -f。例如,如果想显示时间,但是不能确定是使用time命令还是date命令,就可以输入下面两条命令中的任意一条:

1
2
whatis time date
man -f time date

您将看到类似下面的显示信息:

1
2
3
4
5
time (7)             - overview of time and timers
time (3am) - time functions for gawk
time (1) - run programs and summarize system resource usage
time (2) - get time in seconds
date (1) - print or set the system date and time

第1、2、4行不是指向第1节的,可以忽略这三行。查看第3、5行,就可以知道您需要使用的命令是date。

众所周知,在输入man命令时,可以指定一个特定的节号(例如man 1 date)。至于man -f或者whatis命令,就不能再指定具体的节号。Unix总是搜索整个手册。因此,查找手册包含什么内容最好输入:

1
whatis intro

这样将会显示每个intro页的简要说明,例如:

1
2
3
4
5
6
7
8
intro (1)            - introduction to user commands
intro (2) - introduction to system calls
intro (3) - introduction to library functions
intro (4) - introduction to special files
intro (5) - introduction to file formats and filesystems
intro (6) - introduction to games
intro (7) - introduction to overview and miscellany section
intro (8) - introduction to administration and privileged commands

搜索命令:apropos

当希望学习某条具体的命令时,可以使用man来显示该命令的说明书页。但是,如果您知道想做什么,但是却不能确定使用哪条命令,该怎么办呢?

解决方法就是使用带有-k选项的man命令。这样将搜索NAME节中包含特定关键字的命令(字母k代表“keyword”)。例如,假如您希望查找手册中与手册自身相关的所有条目,则可以输入:

1
man -k manual

为了方便起见,可以使用单个单词apropos待替man -k:

1
apropos manual

apropos命令搜索所有的单行命令描述,查找那些包含有指定字符串的描述。为了使该命令的功能更强大,在该命令中Unix不区分大小写字母。下面是上例的一些示例输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
aclocal-1.16 (1)     - manual page for aclocal 1.16.1
apropos (1) - search the manual page names and descriptions
automake (1) - manual page for automake 1.16.1
automake-1.16 (1) - manual page for automake 1.16.1
catman (8) - create or update the pre-formatted manual pages
man (1) - an interface to the system reference manuals
man-recode (1) - convert manual pages to another encoding
manconv (1) - convert manual page from one encoding to another
mandb (8) - create or update the manual page index caches
manpath (1) - determine search path for manual pages
manual_user_enter_context (3) - determine SELinux context(s) for user sessions
qemu-qmp-ref (7) - QEMU QMP Reference Manual
whatis (1) - display one-line manual page descriptions
whereis (1) - locate the binary, source, and manual page files for a command

Info系统

Info系统是一个联机帮助系统,独立于Unix手册,用来记录GNU实用工具。因为许多类型的Unix——包括几乎所有的Linux系统,都使用GNU实用工具,所以大多数人发现了解如何同时使用联机手册和Info非常有用。

从表面上看,Info与联机手册有点相似。信息存储在文件中,每个文件一个主题,这与说明书页相似。这些文件称为Info文件,而且要阅读它们时,需要使用info程序。为此,只需键入info,后面跟着命令的名称即可。

1
2
man date
info date

如果不能确定希望学习哪条命令,或者您希望浏览系统,则可以输入info命令本身:

1
info

当以这种方式启动Info时,它显示一个称为目录节点Directory Node的特殊节点。目录节点包含主要主题的列表,因此可以认为它是整个Info系统的主菜单。

在Info系统中有许多命令可以使用,下图总结了一些最重要的命令。

通用命令
q 退出
h 启动帮助向导
? 显示命令摘要列表
阅读节点
<PageDown> 显示下一屏
<Space> 显示下一屏
<Space> (在节点底部时)跳转到下一个节点
<PageUp> 显示上一屏
<Backspace> 显示上一屏
<Delete> 显示上一屏
<Backspace> (在节点顶部时)跳转到上一个节点
<Delete> (在节点顶部时)跳转到上一个节点
在节点中移动
b 跳转到当前节点的开头
<Up> 将光标向上移动一行
<Down> 将光标向下移动一行
<Right> 将光标向右移动一个位置
<Left> 将光标向左移动一个位置
在同一个文件中从一个节点跳转到另一个节点
n 跳转到同一个文件的下一个节点
p 跳转到同一个文件的上一个节点
t 跳转到顶节点(Top Node,文件中的第一个节点)
从一个文件跳转到另一个文件
<Tab> 将光标移动到下一个链接上
<Shift>-<Tab> 将光标移动到上一个链接上
<Return> 到达链接指向的新节点或文件
l 跳转到上一个(刚才观看的)节点
d 跳转到目录节点(主菜单)

显示环境变量:env、printenv

为了显示默认变量,可以使用命令env:

1
env

在许多系统上,还有另外一个命令可以是用,这个命令是printenv:

1
printenv

名称printenv代表“print environment variables”。

显示shell变量:set

使用不带选项或者参数的set命令可以显示所有的shell变量以及它们的值:

1
set

显示及使用变量的值:echo、print

echo命令的任务就是显示赋予它的任何对象的值。为了显示一个变量的值,需要使用一个$(美元符号)字符。后面跟着用花括号括起来的变量名。例如,显示变量TERM的值,可以输入:

1
echo ${TERM}

如果没有歧义,也可以省略花括号:

1
echo $TERM

在shell中,一些标点符号字符称为“元字符”,它们拥有特殊的含义。为了防止shell解释元字符,需要将元字符包含在双引号中。这就告诉shell照字面意义接受字符。例如,为了显示尖括号中的TERM值。您可以输入下述命令:

1
echo The terminal type is <$TERM>.

但是,<和>字符是元字符,表示“重定向”,所以该命令不能正常运行。为此,您需要使用:

1
echo "The terminal type is <$TERM>."

所有的shell都允许使用echo命令显示文本和变量。至于Korn shell,还可以使用print命令:

1
print "The terminal type is $TERM."

Bourne shell家族使用变量:export、unset

对于Bourne shell家族,创建变量非常简单。所需做的全部事情就是键入一个名称,后跟一个=(等号)字符,再后跟一个值。变量的值必须是字符串。创建变量的语法为:

1
NAME=value

我们创建一个命名为HARLEY的变量,并将值cool赋给它:

1
HARLEY="a cool boy"

在Bourne shell家族中,每个新变量都自动地被设置成shell变量。使用export命令可以将变量导出到环境中。

因此,此时HARLEY只是一个shell变量。如果启动一个新shell或者运行一条命令,则新进程并不能访问HARLEY,因为它还不是环境变量。下面将HARLEY导出到环境中:

1
export HARLEY

现在HARLEY变量既是shell变量又是环境变量了。如果这时再启动一个新shell或者运行一条命令,那么它们就可以访问HARLEY。

export命令实际上允许同时设置变量并导出到环境中。该命令的语法为:

1
export NAME[=value]..

下面举一个简单的例子:

1
export PAGER=less

正如前面所述,当创建变量时,我们称这是在设置变量。当删除变量时,我们称这是在复位unset变量。变量极少需要复位,但是如果需要的话,则可以使用unset命令。该命令的语法比较简单:

1
unset NAME..

下面举例说明:

1
unset HARLEY WEEDLY

C-shell家族使用变量:setenv、unsetenv、set、unset

在C-shell家族中,使用setenv和unsetenv命令可以设置(创建)或复位(删除)环境变量。设置或复位shell变量时,需要使用set和unset命令。

setenv命令的语法如下所示:

1
setenv NAME [value]

注意,该命令中未使用=(等号)字符。

shell选项:set -o、set +o

shell选项就像on/off开关一样。当打开一个选项时,就说设置了这个选项。这将告诉shell以某种方式运行。当关闭这个选项时,就说复位了这个选项。这也就是告诉shell停止以这种方式运行。

要设置一个选项,可以使用:

1
set -o option

要复位一个选项,可以使用:

1
set +o option

例如,假设shell正在运行,您希望设置monitor选项,则可以使用:

1
set -o monitor

为了复位monitor,可以使用:

1
set +o monitor

要显示shell选项的当前值,可以使用set -o或set +o命令本身:

1
2
set -o
set +o

shell内置命令:type

一些指令在shell的内部,这意味着shell可以直接解释它们。这些指令是内部命令,通常称为内置命令builtin command。其他所有命令是外部命令

一种查看某条命令是不是内置指令的快捷方式就是使用type命令。该命令的语法为:

1
type command...

例如:

1
type date time set

该命令的准确输出依赖于所使用的shell。例如,下面是在我系统上的输出:

1
2
3
date is /usr/bin/date
time is a shell keyword
set is a shell builtin

一些Unix/Linux系统对于内置命令拥有独立的说明书页。使用apropos命令可以查看系统是不是属于这种情况:

1
apropos builtin

Linux还有一个help命令,可以以若干种方式显示builtin说明书页的信息。该命令的语法为:

1
help [-s] [command...]

其中command是命令的名称。

开始时,可以通过输入help命令本身显示一个所有内置命令的摘要列表。

1
2
help
help | less

另外还可以使用help命令显示一条或多条具体命令的信息,例如:

1
help pwd history kill help

可以看出,help本事就是一条内置命令。

最后,如果只希望查看某条命令的语法,可以使用-s(syntax,语法)选项:

1
2
help -s help
help -s pwd history kill

历史列表:fc、history