笔记-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 | echo Tis is a very, very long \ |
命令
以超级用户工作:su
su(substitute userid)命令允许您临时变成另一个用户标识。为此,只需在su命令后输入新的用户标识即可。
1 | [harley]$ su weedly |
当您结束weedly的工作时,您需要做的就是结束当前shell。输入exit命令就可以结束当前shell。一旦结束了新shell,您就会自动返回原来的shell,即用户标识harley。
1 | [weedly]$ exit |
上述例子中,您将用户标识变成weedly,但是仍然在harley的环境下工作。如果希望同时变换用户标识和环境,则需要在su命令名称之后键入一个-(连字符)。注意,连字符的两边都有一个空格。
1 | su - weedly |
现在您在weedly的环境中以weedly的名义工作了。
为方便起见,如果su命令没有指定用户标识,那么默认的用户标识是root。因此,下述两个命令是等效的。
1 | su - |
以超级用户执行一条单独的指令: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 | stty kill ^u |
在系统中查找程序:which、type、whence
查找某个程序是否可用的一种精确方法就是使用which命令,只需在键入的which命令后跟一个或多个程序的名称即可,例如:
1 | which date less vi harley |
我的机器运行以上指令的输出为:
1 | /usr/bin/date |
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 | cal -j 12 2009 |
查看系统信息:uptime、hostname、uname
uptime用来显示系统已经运行多长时间(也就是连续运行)的有关信息:
1 | uptime |
一些典型的输出:
1 | 11:10AM up 103 days, 6:13, 3 users, |
在这个例子中,系统已经运行了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 | obase=16 |
那么您将看到:
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 | whatis time date |
您将看到类似下面的显示信息:
1 | time (7) - overview of time and timers |
第1、2、4行不是指向第1节的,可以忽略这三行。查看第3、5行,就可以知道您需要使用的命令是date。
众所周知,在输入man命令时,可以指定一个特定的节号(例如man 1 date)。至于man -f或者whatis命令,就不能再指定具体的节号。Unix总是搜索整个手册。因此,查找手册包含什么内容最好输入:
1 | whatis intro |
这样将会显示每个intro页的简要说明,例如:
1 | intro (1) - introduction to user commands |
搜索命令:apropos
当希望学习某条具体的命令时,可以使用man来显示该命令的说明书页。但是,如果您知道想做什么,但是却不能确定使用哪条命令,该怎么办呢?
解决方法就是使用带有-k选项的man命令。这样将搜索NAME节中包含特定关键字的命令(字母k代表“keyword”)。例如,假如您希望查找手册中与手册自身相关的所有条目,则可以输入:
1 | man -k manual |
为了方便起见,可以使用单个单词apropos待替man -k:
1 | apropos manual |
apropos命令搜索所有的单行命令描述,查找那些包含有指定字符串的描述。为了使该命令的功能更强大,在该命令中Unix不区分大小写字母。下面是上例的一些示例输出:
1 | aclocal-1.16 (1) - manual page for aclocal 1.16.1 |
Info系统
Info系统是一个联机帮助系统,独立于Unix手册,用来记录GNU实用工具。因为许多类型的Unix——包括几乎所有的Linux系统,都使用GNU实用工具,所以大多数人发现了解如何同时使用联机手册和Info非常有用。
从表面上看,Info与联机手册有点相似。信息存储在文件中,每个文件一个主题,这与说明书页相似。这些文件称为Info文件,而且要阅读它们时,需要使用info程序。为此,只需键入info,后面跟着命令的名称即可。
1 | man 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 |
注意,该命令中未使用=(等号)字符。
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 | set -o |
shell内置命令:type
一些指令在shell的内部,这意味着shell可以直接解释它们。这些指令是内部命令,通常称为内置命令builtin command
。其他所有命令是外部命令。
一种查看某条命令是不是内置指令的快捷方式就是使用type命令。该命令的语法为:
1 | type command... |
例如:
1 | type date time set |
该命令的准确输出依赖于所使用的shell。例如,下面是在我系统上的输出:
1 | date is /usr/bin/date |
一些Unix/Linux系统对于内置命令拥有独立的说明书页。使用apropos命令可以查看系统是不是属于这种情况:
1 | apropos builtin |
Linux还有一个help命令,可以以若干种方式显示builtin说明书页的信息。该命令的语法为:
1 | help [-s] [command...] |
其中command是命令的名称。
开始时,可以通过输入help命令本身显示一个所有内置命令的摘要列表。
1 | help |
另外还可以使用help命令显示一条或多条具体命令的信息,例如:
1 | help pwd history kill help |
可以看出,help本事就是一条内置命令。
最后,如果只希望查看某条命令的语法,可以使用-s(syntax,语法)选项:
1 | help -s help |