第07章 shell的基础知识167203.docx
《第07章 shell的基础知识167203.docx》由会员分享,可在线阅读,更多相关《第07章 shell的基础知识167203.docx(29页珍藏版)》请在冰豆网上搜索。
![第07章 shell的基础知识167203.docx](https://file1.bdocx.com/fileroot1/2023-4/2/a89f0a5f-ee66-4e2f-9b04-53bbd12747ae/a89f0a5f-ee66-4e2f-9b04-53bbd12747ae1.gif)
第07章shell的基础知识167203
第7章 shell的基础知识
目标
完成此章学习后,你将掌握下列内容:
⏹描述shell的作用。
⏹描述某用户登录时发生的事情。
⏹描述用户环境的参数及其功能。
⏹设置和修改shell参数。
⏹理解并能修改特定的环境参数,如PATH和TERM。
⏹配置用户环境,使之能够配合某特定的应用程序。
7.1 什么是shell
注释
shell作为程序,是一个具有交互性的命令行解释器。
它独立于操作系统。
这种设计思路使用户可以灵活地选择最适合用户要求的接口。
shell的作用在于等你键入命令、执行一些特定的功能,然后将经它解释的命令传到操作系统(内核)执行。
本章内容将介绍POSIXshell的交互性特点。
POSIXshell不仅仅执行用户的命令,还通过与用户交互,完成其他功能,且大多数功能在执行用户命令之前就完成了。
shell的功能如下:
⏹搜索命令并执行相关的程序。
⏹将shell未指定数值的变量的值替换为shell变量的值。
⏹对命令进行替换。
⏹用文件名生成字符补齐文件名。
⏹控制I/O重定向和管道。
⏹提供解释性的编程接口,包括测试、分支和循环。
当你登录到UNIX系统时,shell会先为你的终端会话过程定义一些特定的特征,然后显示你的提示符。
这个提示符在POSIX、Bourne和Kshell中被默认为一个$符号。
Cshell的默认提示符是一个百分比符号(%)。
7.2 常用的shell
注释
POSIX是一个遵从POSIX标准的命令编程语言和命令解释器,位于/usr/bin/sh。
它可以执行从终端和文件中读来的命令。
这个shell能够和当前的POSIX标准保持一致,在HP-UX面世时这个标准已被人们所采用。
POSIXshell在很多方面与Kornshell相似。
它支持历史命令、作业控制,还有其他多种有用的功能。
Kornshell是一个命令编程语言和命令解释器,位于/usr/bin/ksh。
它可以执行从终端和文件中读来的命令。
与POSIXshell相似,它也支持历史命令、作业管理,还有其他多种有用的功能。
Kornshell由AT&TBell实验室的DavidKorn开发而成。
Bourneshell是一个命令编程语言和命令解释器,位于/usr/old/bin/sh。
它可以执行从终端和文件中读来的命令。
这个shell缺少许多POSIXshell和Kornshell的特征。
Bourneshell由StephenR.Bourne开发,是AT&TUNIX最初采用的shell。
Cshell是一个命令语言解释器,支持历史命令缓存、类似C语言的语法和作业控制。
它由加州大学伯克利分校的WilliamJoy开发。
rsh和rksh是Bourneshell和Kornshell相应的限制版。
限制版执行环境的功能比一般的shell受到的限制要多。
限制版的shell工作起来就像有几个功能不能实现的标准shell。
使用限制版shell的用户不能进行以下工作:
⏹修改目录。
⏹重设PATH这个环境变量。
⏹在路径名中使用“/”这个字符。
⏹重定向输出。
keyshell是标准shell的扩展版。
它提供层次性的软键菜单,为用户写命令行提供上下文相关的帮助。
keysh由HP和AT&T开发。
各种shell的特征比较见表7-1。
表7-1 各种shell的特征比较
特征
描述
POSIX
Bourne
Korn
C
历史命令
命令可以存在缓存中供修改和重复使用
是
否
是
是
命令行编辑
用文本编辑器修改当前或以前的命令行
是
否
是
否
文件名补齐
在命令行自动完成文件名的键入
是
否
是
是
命令别名
用户可以重命名命令,自动包括命令的选项或缩短长命令行
是
否
是
是
限制版
一个安全性特征,其环境的功能受到限制
是
是
是
否
作业控制
跟踪和访问在后台运行的进程
是
否
是
是
7.3 POSIXshell的特征
注释
UNIX提供的其中一种shell是POSIXshell。
这个shell具有许多Kornshell拥有但Bourneshell没有的特征。
即使你不会用到POSIXshell所有的高级特征,但你会发现它提供了一个非常方便的用户接口。
以下是POSIXshell的一小部分特征:
⏹历史命令
⏹命令行恢复和编辑
⏹作业控制
⏹文件名补齐
⏹别名命令
⏹增强的cd命令用法
⏹高级的编程功能
7.4 别名化
注释
别名是命令的一个新名字。
使用别名可以缩短长命令行,创建新的命令,用别名命令的功能替换原标准命令的功能从而使标准命令执行起来跟以前不同。
别名可以是一个字母或者一个简短的单词。
如,许多人常用命令ps–ef。
其实,用psf更方便。
可以用命令alias创建一个别名。
$aliasname=string
其中name是命令的别名,string是被指定别名的原命令。
如果string有空格,需用括号将其括起来。
别名给使用者提供了方便,可以节省键入量、创建新的命令,使系统能够理解并执行常见的键入错误。
键入别名命令和键入其他命令看上去是一样的。
用户不知道其所执行的命令是UNIX系统的原有命令还是指向UNIX命令的别名命令。
shell在执行命令之前会扩展这个别名,然后执行最终的命令行。
如果用与系统交互的方式设定别名,这个别名将一直保持有效,直到退出系统为止。
有些用户发现shell的这种别名特征非常灵活,因此他们使其使用的UNIX系统能辨认出他们在另一个操作系统中常用的命令(如:
aliasdir=ls或者aliascopy=’cp-i’)。
别名常用来节省输入完整的路径名。
不带参数的alias会显示所有当前定义的别名。
要列出某特定别名的值,用aliasname。
可以用unalias关闭别名,用法是:
unaliasname
例子
在一个命令行上可以使用几个别名,如:
$aliasgo=’cd’
$aliasthere=/home/user3/tree/ford/sports
$gothere
$pwd
$/home/user3/tree/ford/sports
为了能在一个命令行上引用多个别名,须在定义别名时将最后一个字符设为空格;不然,shell不会认为下一个词是别名。
7.5 文件名补齐
注释
当访问一个带长文件名的文件时,文件名补齐非常方便。
当输入的字符足够唯一确定该文件名时,按EscEsc,这时POSIXshell会补齐文件名剩余的部分。
如果提供的字符串还做不到唯一,POSIXshell将无法解析该文件名,这时必须再提供一些信息。
出现文件名冲突时,终端会发出鸣叫。
只要冲突一消失,shell就会补齐文件名。
可以按Esc=列出可能选择的文件名。
POSIXshell显示可选的文件名后,就可以用编辑器命令补上能唯一标记目标文件名的后续字符,然后按EscEsc补齐文件名。
文件名补齐可以用在文件名路径的任何地方。
如:
$cdtrEscEscdoEscEscrEscEsc
将显示如下结果:
$cdtree/dog.breeds/retriever
7.6 命令历史
注释
POSIXshell维护着一个历史文件,该文件存储着曾经输入的命令。
也可以重输入这些命令。
UNIX系统对历史文件的维护跨越各个登录进程。
history命令会显示最近输入的16个命令,每行用命令号开头。
当重输入命令时,指定该命令相应的命令号即可。
可以显示超过或少于16个的最近输入的命令:
history–n
其中n是要显示的命令数目。
可以显示一系列命令号:
historyaz
其中az是一个命令号或一系列命令号。
HISTSIZE参数定义可以访问历史命令的数目(默认的HISTSIZE值是128)。
HISTFILE参数指定的是存储已输入命令的文本文件(默认的HISTFILE是.sh_history)。
历史命令列表显示出来后,可以恢复、编辑或者重输入任何其中一个命令。
7.7 重输入命令
注释
可以运行命令历史列表中的任何命令,键入:
rc
其中c是命令号。
也可以输入一个命令的首字母,这样会执行以该字母开头的最近输入的命令。
如:
$history
1date
2catfile1
3ls–l
$rd
MonJul410:
03:
131994
7.8 回调命令
注释
内嵌在UNIXshell的编辑器中,应用最广泛的是vi,这个编辑器的基本功能是用来演示命令行编辑。
将在后面的章节中学习vi的详细用法。
shell的历史命令机制允许恢复以前输入的命令,这样不用重新键入这个命令行就可以重执行该命令。
还可以用vi编辑以前输入的命令行。
这些特性可节省大量的键盘输入。
如果你不是一个出色的打字员,还可以节省大量的时间和烦恼。
为了让vi命令在POSIXshell的历史机制中发挥作用,需要在你的环境中设定EDITOR变量。
如果执行了env命令,应该看到下面这行:
$env
.
.
EDITOR=/usr/bin/vi
如果这个参数还没有设好,执行下列命令设置这个参数:
$EDITOR=/usr/bin/vi
$exportEDITOR
这两个命令告诉POSIXshell你想用vi编辑器来回调和编辑历史命令。
如果想确保每次登录时EDITOR参数已被正确设置,可以将这些命令放在.profile文件中。
如果不设定EDITOR变量的值,其默认值是/usr/bin/ed指定的值。
要回调前一个命令,只需按Esc。
这时还不会看到屏幕有什么反应。
按Esc的作用是将你置身于POSIXshell的vi环境中。
这时可以使用许多一般的vi命令。
如,按k在命令栈中移到后一个命令,继续按k,会看到命令行每次显示一个历史命令。
同样,如果按
j,会按相反方向滚动。
当看见想重新执行的命令出现在命令行上时,按Return。
用history命令可以看到最近16个命令行及其命令号。
如果想执行某命令,按EscnG,n是历史命令列表中的命令行号;G是vi模式中的一个命令,作用是到达某个命令行。
7.9 命令行编辑
注释
经常需要回调一个命令,然后重新执行,但首先要做一些小的修改。
这时可以先按Esc,然后按k,这时回调的是最后一个命令。
如果知道该命令的行号,可以先键入命令行号,然后键入G,这样可以回调要执行的命令。
如,假定history命令的结果是:
120env
121ls
122cd
123cd/tmp
124pwd
125history
如果按Esck,接着键入122G,下面的命令行会被回调:
cd
在命令栈中定位命令的另一种方法跟以前一样,先按Esck,然后按/pattern。
如,按Esck进入命令栈后,键入/cd,可以定位最近的cd命令。
如果再键入一个/,回调的是倒数第二个cd命令。
一旦搜索了一个命令样式后,键入n同样会搜索下一个符合样式的命令。
定位到命令后,可以按Return执行该命令,或者用下一节介绍的编辑命令进行编辑。
如果不想执行这个命令,键入Ctrl+c取消这个命令。
7.10 命令行编辑(续)
注释
当你键完一个很长的命令行时,常会发现在行首有一个错误。
这时,你只能按Backspace,重新键入错字后面的内容。
POSIXshell可以使你在执行命令之前修改错误和修改命令行的部分内容。
这里使用的还是vi的编辑命令。
为了修改一个命令行,须按Esc进入编辑模式。
这个模式可以编辑正在键入的命令行和用Esc和k恢复的命令行。
如果在编辑模式里,vi命令就可以工作了。
如,x可以删除一个字符,h和l可以在一行中左移和右移,cw可以修改一个词,dw可以删除一个词,等等。
用vi命令可以访问命令栈和编辑命令行。
这种设计思路的优点是:
一旦熟悉了vi命令,就掌握了使用命令栈的必要工具,不必学习另一种接口、另一组命令。
用以下vi命令可以编辑命令行:
h,Backspace,l,Space,w,b,$移动光标
x,dw,p删除和粘贴文本
r,R,cw修改文本
a,i进入键入模式(inputmode)以添加文本
为了能用vi命令访问命令栈,需要设置变量EDITOR=/usr/bin/vi(其他可选的编辑器有gmacs和emacs)。
将每个命令行想像为一个微型的vi进程,你在每个命令行头部均处于输入状态。
要访问以前输入的命令,调用控制光标上移的vi命令,但在调用vi命令之前必须按Esc进入命令状态。
这时可以键入上移光标的vi命令——按k。
连续按多个k就上移多个历史命令。
当希望运行的命令出现时,仅按Return键就可以执行这个命令,然后这个命令被追加到你的命令栈中。
POSIXshell的主要好处是既可以输入当前的命令,也可以输入以前的命令。
没有必要按回格键返回到要修改或重新开始的地方。
在输入了一个有小错误的长命令行或者要修改参数时,这个特点尤其有用。
出现这个特点之前,必须重新输入整行,或者按Backspace,然后重敲。
基于POSIXshell这个行编辑的特点,可以显示一个以前输入过的命令行,用vi命令对这行进行修改,然后执行。
所做的修改可以简单到只改一个字符,也可以广泛到将这个命令的整个参数列表都修改掉。
例子
$cp/usr/lib/X11/app-defaults
Usage:
cpf1f2
cp[-r]f1...fnd1
以上的命令原本应该是cd,不是cp。
POSIXshell可以修改这行而不用重敲。
只是先按Esc,然后按k,这个命令行就会重现。
按l,移动到cp的p字母处,然后用r命令将p替换为d。
此时命令如下:
$cd/usr/lib/X11/app-defaults
这时仅仅按一下Return就可以执行cd命令。
如果在编辑命令行过程中存在困难,按一下Break就可以取消修改,这时可以回到正常的shell提示符下,这样就可以再试一次。
在编辑POSIXshell的命令行时不要使用箭头键。
除了使用h和l键外,还可以使用Backspace和空格条。
字符错位是另一种常见的打字错误。
假设输入下面这行,其中ford的r和o写反了。
$cd$HOME/tree/car.models/frod/sports
cd:
directorynotfound
可以用以下的步骤修改错误,然后再执行:
Esc
k 按一次或多次直到显示出目标命令行。
w 按多次直到光标移到frod的f下。
l 光标应该位于frod的r下。
xp 删除r,在o后面粘贴r。
Return 执行该命令行。
7.11 用户环境
注释
环境描述了会话过程的许多内容,其包括以下信息:
⏹主目录的路径名
⏹在哪里存放email
⏹工作的时区
⏹登录的身份
⏹shell从哪里搜索命令
⏹终端类型和大小
⏹应用程序所依赖的其他东西
例如,命令vi和more需要知道使用的终端类型,这样它们才可以正确地格式化输出结果。
用户环境可以比喻为办公室环境。
在办公室里,像照明、噪声和温度等对于所有的工作人员都是一样的。
办公室中只有你才拥有的因素构成了你的特定环境。
这些因素包括:
你在做什么工作、你的办公桌的布置、你和办公室里其他人的关系等等。
正如你的工作环境对于你是唯一的一样,你的用户环境也是唯一的。
许多应用程序要求在某些方面设置环境,这可以通过修改.profile文件来实现。
当登录进系统时,可以运行命令env查看环境。
它会显示设置在环境中的每一个因素。
在env命令运行结果的列表中,“=”左边是已经设置的不同环境变量的名字,“=”右边是相关参数的值。
查看env
(1)可以获得更多的细节信息。
每个环境变量的设置都有其理由。
以下是一些常见的环境变量及其含义:
TERM,COLUMNS和LINES
描述所使用的终端
HOME
主目录的路径名
PATH
搜索命令地点的列表
LOGNAME
登录用的用户名
env和HISTFILE
专用的POSIXshell变量
DISPLAY
专用的XWindow变量
这些变量中有一些由系统来设定,其他的在/etc/profile或.profile中设定。
7.12 设定shell变量
注释
shell变量与运算式的变量类似。
它是一个名字,代表一个数值。
UNIX的变量分配就是将一个值与一个变量名联系起来。
这样可以通过变量名访问这个值。
如果这个值被修改,仍然可以通过同样的变量名访问到新的数值。
将一个值分配给shell变量的语法是:
name=value
可以在终端的shell提示符后面或者在shell程序中输入这个语句。
注意在等号(=)的前后都没有空格。
这样可以保证shell不会试图将这个变量数值分配语句误解为一个命令调用语句。
区分shell变量名和shell变量值是很重要的。
通过执行预分配语句设定变量值,如:
TERM=70092。
这就要求shell记住名字TERM,以及当发生访问TERM变量值的请求时,用70092作出应答。
变量命名规定
变量名必须以一个字母开头(a-z和A-Z),可以包含字母、数字或下划线。
对于变量名中字符的数目没有限制。
7.13 两个重要的环境变量
注释
PATH
PATH变量代表的是shell搜索命令的一系列目录。
这样只需键入一个命令名,不用输入该命令的完全路径名(如:
键入vi,不用键入/usr/bin/vi)。
下面是一个默认PATH变量的例子:
PATH=/usr/bin:
/usr/contrib/bin:
/usr/local/bin
这个例子表明,键入一个命令,shell将首先在/usr/bin搜索该命令,接着是/usr/contrib/bin,以此类推,直到在这些目录找到或者都找不到该命令。
如果键入的命令在任何一个PATH目录中都找不到,在屏幕上会显示一个错误信息:
command:
notfound。
TERM
TERM变量是一个描述使用终端类型的环境变量。
为了使许多命令能正确执行,这些命令需要知道使用的终端类型。
如,ls命令需要知道屏幕上有多少列,more命令需要知道屏幕上有多少行,vi命令需要同时知道屏幕的行和列的数目,以及其他更多关于终端类型的信息,这样它才能正常地工作。
UNIX系统设置终端类型变量的默认方法是提示用户输入正确的终端类型:
TERM=(hp)
这时要么按Return把终端类型设为hp,要么键入正在使用的终端类型。
终端类型hp是一个标准的80列24行惠普终端。
系统管理员已经设置好了你的系统,UNIX系统不会向你提问你的终端类型。
在这种情况下,应该用env命令查看TERM变量值。
如果使用的工作站仅用一种显示器,TERM变量很可能已被正确设置,不必修改。
当使用命令more或vi时,如果终端表现很异常,查一下TERM变量的值。
如果它已被正确设置,执行命令tset。
这个命令将按TERM变量的值设置终端的特征。
7.14 常见变量的分配值
常见变量的分配值
用粗体显示的变量名是需要设置的变量。
⏹EDITOR=/usr/bin/vi 用vi命令作行编辑。
⏹ENV=$HOME/.shrc 在启动shell时执行$HOME/.shrc。
⏹HOME=/home/user3 指定登录目录。
⏹FCEDIT=/usr/bin/vi 对历史命令行启动vi编辑进程。
⏹~(波浪线) 在POSIXshell中相当于主目录。
⏹HISTFILE=$HOME/.sh_history 指定存储所有输入过的交互式命令的文件。
⏹LOGNAME=user3指定登录标识符或者用户名。
⏹MAIL=/var/mail/user3系统使用的邮箱。
⏹OLDPWD=/tmp指定(说明)前一个目录的位置。
⏹PATH=/usr/bin:
$HOME/bin指定搜索命令的目录。
⏹PS1=指定主提示符。
PS1=‘[!
]$’显示命令行号和提示符。
PS1=‘$PWD$’显示当前工作目录和提示符(注意:
必须用单引号(’)括起来,不能用双引号(”))。
PS1=‘[!
]$PWD$’显示命令行号、当前工作目录和提示符。
⏹PWD=/home/user3/tree指定当前工作目录。
⏹SHELL=/usr/bin/sh指定命令解释器程序。
⏹TERM=2392a指定你的终端类型。
用命令:
eval‘test–s–Q-h’
在启动过程中,系统会读取文件/etc/ttytype,用里面提供的信息正确设置终端类型。
当有不同类型的终端联接到你的系统时,这点非常有用。
⏹TMOUT=300 如果在指定的秒数内没有键入命令或回车键,shell会终止或者超时。
⏹TZ=EST5EDT 指定系统用来显示时间的时区。
TERM变量
必须正确设置TERM变量,这样UNIX系统才能知道终端的特征。
许多命令需要知道正在使用的终端类型才能正确输出结果。
如more和vi为了正确控制屏幕输出结果,必须知道显示器的行数和列数。
可以通过变量分配直接定义TERM变量的值,或者用tset命令分配,这个命令取决于正在使用的终端类型和文件/etc/ttytype中相应的值。
表7-2总结了一些不同终端模型及其对应的TERM值。
如果使用的终端模型不在其中,可以查看/usr/lib/terminfo下的子目录。
表7-2 不同终端模型及其对应的TERM值
终端模型
TERM值
HP2392a
2392a
HP70092
70092
Hp70094
70094
vt100
vt100
Wyse50
wy50
Mediumresolutiongraphicsdisplay
(512600pixels)
300l或者hp300l
Highresolutiongraphicsdisplay
(1024768pixels)
300h或者hp300h
HP98550displaystation
(12801024pixels)
98550、hp98550、98550a或者hp98550a
HP98720orHP98721SRX
(12801024pixels)
98720、hp98720、98720a、hp98720a、98721、hp98721、98721a或者hp98721a
HP98730orHP98731TurboSRX
(12801024pixels)
98730、hp98730、98730a、hp98730a、98731、hp98731、98731a或者hp98731a
7.15 登录时发生的事