|
|
第十一章 Korn shell 翻译:hfzheng hfzheng@sohu.com 转载请保留此信息 作为命令翻译器的shell 在任何UNIX环境下,shell通常作为命令翻译器。通过对命令行方式下键入的命令或者放在脚本文件中的命令行进行翻译,可以和内核进行交互。Shell接收、分析、处理来自用户或者脚本文件的输入,作为命令翻译器对这些输入进行翻译,并对不正确的命令给出错误信息。 Shell是可以切换的,因此用户在任何时候都可以选择使用哪个命令翻译器,在Bourne shell、C shell、Korn shell之间切换是很容易的。 尽管shell最终负责确保命令行提示符下键入的任何命令的正确执行,shell还有其他重要的功能。 作为命令翻译器的shell的职责: 1、shell在所有由shell环境变量PATH定义的目录位置中搜索命令,shell从左到右搜索PATH定义的、以:分割的目录; 2、shell设置管道、输入输出重定向和后台处理; 3、shell可以由用户定制,通过为命令或者命令序列创建别名,或者当别名不够时创建函数来定制; 4、通过设置shell变量TERM,shell可以适应不同的终端环境; 5、shell保存了键入命令完成机制; 6、shell在历史列表中保存了先前执行过的命令,可以用于重新运行或编辑; 7、通过使用shell初始化文件,系统可以为每个用户定制shell。 输入输出重定义和管道 接下来的部分讨论重定向和输入输出管道 重定向数据I/O 通常情况下,shell从键盘接收或者读取输入的命令,显示或者写命令输出到终端屏幕。不过,你可以使用重定向字符<和>来告诉shell重定向命令输入和输出。 I/O重定向通常用于命令行的输入和输出到文件中或者到shell脚本中。 输入重定向从文件中读取必要的输入而不是接收自键盘,输出重定向把一个命令的输出送到一个文件或者送到其他命令(使用管道)而不是送到终端屏幕。 文件描述子 由shell创建的每个进程都关联着一个文件描述子,列出如下: 文件描述子功能 0 stdin标准输入 1 stdout标准输出 2 stderr标准错误 这些描述子由shell所使用,用于确定命令的输入来自何处,命令的输出和出错信息送到什么地方。 标准命令输入和输出 以下部分对标准命令适用: 1、标准输入(stdin):文件描述子总是0 2、标准输出(stdout);文件描述子总是1 3、标准出错(stderr):文件描述子总是2 处理文件内容所有命令都通过读标准输入、写标准输出来实现的。 重定向标准输入、标准输出、标准出错 可以修改标准输入、标准输出、标准出错的默认行为。 重定向标准输入 下面解释如何重定向一个标准输入命令: command < filename 或者 command 0< filename command从一个名为filename的文件中读取它的输入,而不是从键盘中接收。例如: $ mailx user1 < ~/dante 重定向标准输出 下面解释如何重定向一个标准输出命令: command > filename 或者 command 1> filename command把结果输出到一个名为filename的文件中,如果文件filename不存在,将会被创建,如果文件filename存在,重定向覆盖文件filename的内容。例如: $ ps –ef > process_list 使用添加模式重定向标准输出 下面解释如何使用添加模式重定向一个标准输出命令: command >> filename 命令的输出被重定向到文件filename中,如果该文件存在,则把命令输出添加到文件内容的末尾。不过文件filename不存在,则创建该文件,例如: $ cat /etc/passwd > my_file ; cat my_file $ echo “That’s my passwd file” >> my_file; cat my_file 重定向标准错误 下面的示例显示了如何重定向一个标准错误: command 2> /dev/null 命令的任何错误信息都被送到/dev/null文件中。这在抑制不重要的错误时非常有用,这样可以没有任何错误显示在终端屏幕上,例如: $ find /etc –type f –exec grep PASSREQ {} \; -print 2> /dev/null 重定向标准输出和标准错误 下面的示例显示了如何重定向标准输出和错误: command 1> filename 2>&1 语法2>&1告诉shell重定向标准错误(stderr 2)到与标准输出(stdout 1)重定向相同的一个文件中,例如: $ ls /var /no 1> dat 2>&1 管道特点 shell使你可以更有效地把两个命令连接在一起,这个连接就是管道。在命令行中建立管道就是把一个命令的输出作为作为另外一个命令的输入。管道由字符|表示,放在两个命令之间。 命令格式 command | command 一些使用管道的基本示例 如果两个命令,第一个命令写命令输出到标准输出,第二个命令从标准输入中读取输入,则可以在这两个命令之间创建管道。 例如: $ who | wc –l 第一个命令的输出被直接连接到第二个命令的输入。Who命令的输出从不输出到终端屏幕上,因为已经被管道化为wc命令输入。 要得到当前系统中活动进程的总数目,使用下面命令: $ ps –ef | wc –l 要得到/etc目录下的所有子目录列表,执行下面命令: $ ls –F /etc | grep “/” 创建管道 可以创建用来连接多个命令的管道,例如: $ head –10 dante | tail –3 | lp Korn shell的设置 用来控制korn shell行为的设置都是开关变量,他们都是boolean变量,因此,每一个都可以ON或者OFF: 打开一个设置,键入: $ set –o option_name 关闭一个设置,键入: $ set +o option_name 在I/O重定向过程中保护文件内容 重定向标准输出到一个已经存在的文件中时将导致数据丢失,为了防止发生数据丢失,shell支持noclobber设置: 使用set命令可以激活noclobber设置,例如: $ set –o noclobber 使noclobber失效 要暂时使noclobber设置失效可以在命令行上使用>|语法,noclobber设置只是对该命令行失效,文件的内容被覆盖: $ ls –l >| file_new 要永久关闭noclobber设置,执行以下命令: $ set +o noclobber korn shell的文件名称完成 文件名称完成,通常称为文件名扩展,是允许你键入文件名称的第一个字符,然后通过一个特定的键序列来告诉korn shell来完成文件名称的其他部分的一种机制。 在korn shell中用于文件名称自动完成的键序列有Esc和\键。 使用文件名称完成: 要激活文件名称完成机制,你必须设置EDITOR变量到/usr/dt/bin/dtpad。该机制也要求用户打开vi设置,在插入模式下启动vi。 $ set –o vi 为了调用文件名称完成,键入ls命令,后跟文件名的一个或者多个字符,然后按顺序按下列键:Esc和\。 如果shell发现以指定字符开头的文件,shell将在命令行上打印出完整的文件名。 你也可以要求shell列出所有以你键入的字符开头的文件名称,这项功能可以通过按顺序下面两个键得到:Esc和=。 Korn shell的变量 变量是一个名称,用来事项内存中的一个临时存储区域,变量包含有定制shell和其他进程正确执行自身功能所需要的信息,shell允许你把值存储在变量中。 Shell编程使用两种类型的变量:局部变量和环境变量,根据习惯,局部变量通常小写,环境变量通常大写。 1、局部变量:为创建它的shell所私人拥有,并不会传给由shell开启的任何进程; 2、环境变量:由父进程传给子进程,依此类推。一些环境变量继承自login shell,其他的环境变量在用户的shell初始化文件、shell脚本或者命令行中创建。 下面总结了korn shell中用来设置、取消设置、查看两种不同类型的变量的命令: 动作环境变量 局部变量 设置变量export VAR=valuevar=value 取消设置变量unset VARunset var 显示所有变量env, export(只列出环境变量)set(列出所有变量) 显示变量值echo $VARprint $var 如果一个有效的shell变量跟了$符号,shell把它作为在这一点上从存储在变量中的值代替变量的标记。 变量的参考值 echo命令可以列出存储在shell变量中的值,例如: $ echo $SHELL 显示变量 set命令列出所有shell变量(局部变量和环境变量)以及他们的设置值,例如: $ set 要使得一个环境变量的值被子shell所知,要使用export命令输出,你可以使用export命令来列出所有环境变量及其当前值。 $ export 设置shell变量 局部变量 局部变量的赋值采用下面的语法: var=value 在等号的两边不可以有空格,例如: $ private=/home/user1/private 环境变量 环境变量的赋值采用下面的语法: set VAR=value 例如: $ export office=/home/user1/office 取消设置环境变量 存储在局部变量和环境变量中的值可以使用下面语法删除: unset VAR unset var 例如,取消设置一个变量: $ unset private 在登录时由shell设置的变量 下面给出了登录时由shell设置默认值的shell变量的一个基本列表: 变量功能 EDITOR为shell定义默认的编辑器 FCEDIT为fc命令定义编辑器,fc被历史机制所使用,用来编辑前面执行过的命令。 HOME不带参数的cd命令所进入的目录 LOGNAME设置用户的登录名 PATHshell要查找一个需要执行命令时搜索的一个以:分割的目录列表 PS1基本的korn shell符号:$ PS2第二个命令提示符,通常为:> SHELL shell名称(例如/bin/ksh) 定制korn shell变量 接下来的部分讲述如何定制korn shell变量。 Shell变量PS1 shell提示符字符串存储在shell变量PS1中,你可以根据你自己的需要来定制它: $ PS1=”$LOGNAME@’hostname’$” username@hostname 在这个示例中,提示符显示用户的登录名和系统主机名 用户名从变量LOGNAME中读取,主机名则来自hostname的输出。当用户从不同的主机上登录时该提示符可以显示正确的信息。 第二个示例用于显示如何在提示符定义中使用另外一个变量的值。 $ ILU=”I LIKE UNIX” $ PS1=”$ILU > “ I LIKE UNIX > 备注:在每次shell调用的时候,新的shell提示符都会出现,要把它包含在一个通常名为.kshrc的用户初始化文件中。 PATH变量 PATH变量存储由冒号分割的目录路径名称列表,当你从命令行中调用命令时,shell从左到右所有目录以寻找要执行的命令。 第一个找到的命令就是由shell执行的。 如果shell在列出的目录中找不到该命令,shell将显示下面的错误信息: ksh:command_name:not found 不过命令可能驻留在其他没有在PATH中指定的目录中,因为,shell限制在PATH中指定的目录中搜索。 Shell如果在PATH指定的目录中找不到该命令,则命令不可以被执行,用户可以在命令行中使用绝对路径来键入命令,例如: $ usr/bin/id 如果shell正确执行了命令,如果使用绝对路径方式成功执行了命令,那么用户就需要检查PATH变量,以确保在搜索列表中列出了该目录,例如: $ echo $PATH 扩展PATH变量 在下面的示例中,PATH变量扩展到包含有用户的home目录: $ print $PATH /usr/openwin/bin:/bin:/usr/bin:/usr/ucb: $ $ PATH=$PATH:~ $ echo $PATH /usr/openwin/bin:/bin:/usr/bin:/usr/ucb:/export/home/user1 PATH变量,默认情况下,一个环境变量自动把值传给子shell。
Korn shell的元字符 元字符,对于shell而言有特殊的含义,是任何shell强大功能的特征。不过在告诉shell需要屏蔽、忽略元字符的特殊含义时,要通过一个称为引用的过程来完成。 Shell用于引用的特殊字符包括\(反斜杠)、’(单引号)和”(双引号)。 使用反斜杠\的引用 把反斜杠\放在元字符的前面,可以禁止shell对元字符进行翻译,例如,一个文件使用了星号*作为它的名称,要删除该文件,星号*必须要用反斜杠\来屏蔽。 $ ls dat1 dat2 dat3 dir1 dir2 * $ rm \* 所使用单引号和双引号的引用 把元字符放在引号之中,可以禁止shell把他们解释为元字符,和反斜杠\不同的是,反斜杠\只能屏蔽单个特殊字符,而引号一次可以屏蔽多个字符: 单引号(’):告诉shell忽略所有括起来的元字符 双引号(”):告诉shell忽略大多数括起来的元字符 任何时候下面三种元字符放在双引号中仍然保持各自特殊的含义。 反斜杠(\) 美元符号($) 反引号(‘‘) 示例: $ echo ‘$SHELL’ $SHELL $ echo “$SHELL” /bin/ksh $ echo “\$SHELL” $SHELL $ echo ‘\’ \ $ echo “\” > ^C 命令替换 任何放在反引号(‘‘)之中的UNIX命令会被shell执行,并显示输出结果。例如: $ echo date date $ echo ‘date‘ Tue May 2 14:10:05 MDT 2002 在所有的UNIX shell中常用反引号用于命令替换,不过,korn shell为命令替换提供了另外一个方法: $ echo pwd pwd $ echo $(pwd) /home/usr1 历史机制 Korn shell保存了最近键入的命令历史,利用历史机制用户可以查看、重复、编辑、修改先前执行的命令。 History命令 Korn shell保存历史命令在一个由HISTFILE变量指定的文件中,默认文件是$HOME/.sh_history。 使用HISTSIZE变量可以指定保存的命令数,如果没有设置,将保存最近128条命令。 使用korn shell的行内编辑器可以编辑和重新运行前面执行过的命令。例如vi。行内编辑器由环境变量EDITOR指定。 设置EDITOR变量为history命令指定行内编辑器如vi。 默认情况下,history命令显示最近16条命令到标准输出,例如: $ history …… 157 date 158 cd /etc 159 touch dat1 dat2 160 ps -ef 161history 左边的数字是命令的编号,使用这些数字你可以告诉shell要重新执行哪条命令。 要显示不带命令编号的历史记录,使用如下命令: $ history –n 显示改命令和它前面四条命令,执行下面命令: $ history -4 反序显示历史记录列表,执行下面的命令: $ history –r 显示最近使用的cd和ls命令,执行以下命令: $ history cd ls r命令 r命令是一个简单的korn shell命令,用于重复一个命令,例如: $ cal $ r 可以使用带命令编号的r命令来重新执行某一命令,例如下面示例重新执行命令历史记录中编号为210的命令: $ r 210 也可以使用r命令来重新执行某一特定字符开头的命令,在下面的示例中,shell重新执行最近出现的以c开头的命令: $ r c 可以使用r命令来重新某一先前的命令,对该命令简单编辑,然后执行修改后的命令: $ history $ r c cd /etc $ r etc=tmp cd /tmp 使用vi命令来编辑前面执行过的命令 你可以访问历史记录中的命令,使用vi来编辑,然后执行修改后的命令,步骤如下: 1、确认默认的编辑器是vi; $ echo $EDITOR /bin/vi 2、键入history列出命令历史记录: $ history 3、按Esc键来访问命令历史列表中的命令,使用下面的光标移动键在历史命令列表中上下滚动: k=上移一行 j=下移一行 l=右移光标 h=左移光标 4、使用vi命令来编辑任何前面执行过的命令; 5、要执行修改后的命令,按回车键; Korn shell别名实用工具 别名是korn shell中的一个短助记符。使你可以定制和缩写一个UNIX命令,别名使用alias命令定义。 命令格式 alias name=command_string 例如: $ alias dir=’ls -lF’ shell保存了一个别名列表,当键入一个命令时,如果命令行中的第一个字是一个别名的话,shell使用别名中的文本来代替该字。 别名创建以后,应当遵循以下规则: 1、等号的两边不能有空格; 2、如何命令字符串中包含有任何选项、元字符或者空格必须加上引号; 3、单个别名中的每个命令用分号分开; 预定义的korn shell别名 korn shell包含了一些预先定义的别名,可以使用alias来查看,任何新定义的别名也会被显示: $ alias 下面给出别名定义列表 别名值定义 autoload typeset –fu 定义如何装载一个函数 command command 执行一个简单命令,抑止shell函数查找 functionstypeset –f 显示函数列表 history fc –l 历史文件命令列表 integertypeset –i 声明一个整型变量 local typeset 为shell变量和函数设置局部属性 nohupnohup 即使退出登录后任务仍然使任务运行 r fc –e – 再次执行上一条命令 stop kill –STOP挂起一个任务 suspend kill –STOP 挂起一个任务 $$ 用户定义的别名 别名通常用于缩写或者定制经常使用的命令,例如: $ alias h=history $ h 使用rm、cp和mv命令可能会导致数据的意外丢失,作为预防,你可以为带交互选项的这些命令取别名,例如: $ alias rm=”rm -i” $ rm data1 通过为cp –i和mv –i创建别名,shell在覆盖已经存在的文件之前将给出询问。 你也可以是一个别名临时失效,通过在命令行中的别名前面加上一个\符号,\将禁止shell取查找别名列表,这将执行原来的rm命令,例如: $ rm file1 $ \rm file1 命令顺序 你也可以在一个别名中放几个命令,每个命令之间用分号分割,例如: $ alias info=’uname –a; id –a; date’ $ info 在下面的示例中,创建了一个别名,使用管道来把ls –l命令的输出重定向到more命令中,当新创建的别名被调用时,你将得到一个长目录列表,一次一屏,例如: $ alias ll=”ls –l | more” $ ll 删除别名 unalias命令用于从别名列表中删除别名。 命令格式 unalias name 例如: $ unalias h $ h ksh:h:not found Korn shell函数 函数是shell编程中一个极为强大的用于创建定制的命令的特征。函数是按一定顺序组织的一组UNIX命令。使用函数包括以下两个步骤: 1、定义函数 2、调用函数 定义函数 使用如下的通用格式来定义一个函数: function name{command; . . . . . . command; } 一些函数示例 下面的示例创建了一个名为num的函数,用来执行who命令,并把输出重定向到wc命令来显示当前登录到系统中的用户总数: $ function num { who | wc –l; } $ num 下面的示例创建一个名为list的函数,用来执行ls命令,并把输出重定向到wc命令来显示当前目录中子目录和文件总数: $ function list {ls –al | wc –l; } $ list 查看所有已经定义了的函数,执行下面命令: $ function typeset –f 配置Korn shell环境 可以定制的shell环境,通过两个位于home目录中的初始化文件,分别是: 1、~/.profile 2、~/.kshrc Korn shell查看你的home目录以寻找名为.profile的初始化文件和一个通常命名为.kshrc的环境文件。在执行完这些文件中发现的命令后,shell提示符将出现在屏幕上,Korn shell等待输入命令。 ~/.profile文件 .profile文件是一个用户定义的初始化文件,存在于你的home目录中,由login shell在登录时执行一次, 这使你可以定制和修改你的工作环境。 环境变量和终端设置通常在这个文件中设定,如果一个应用要初始化,也可以在这里开启。 如果在.profile文件文件中有一个称为ENV的特殊变量,赋予该变量的文件名称将在下次执行。 ~/.kshrc文件 ENV文件通常称为.kshrc文件,在该文件中定义了Korn shell变量和别名,当korn shell开启一个子shell时ENV文件将会被执行。 以下项目通常在~/.kshrc文件设定: 1、shell提示符定义(PS1、PS2); 2、别名定义; 3、Korn shell函数; 4、历史环境变量; 5、列出Korn shell选项; 读初始化文件 当修改你个人的初始化文件以后,这些修改将在你下次登录的时候起作用。不过,如果你想使这些修改立刻起作用,在~/.profile和~/.kshrc文件使用.点号命令。例如: $ ~/.profile $ $ ~/.kshrc 配置CDE环境 .dtprofile文件 如果你工作在CDE环境中,有另外一个称为.dtprofile的初始化文件。它驻留在你的home目录中,确定一般和用户为CDE定制的设置。.dtprofile文件意味着你的设置可以覆盖默认设置。 在目录/usr/dt/config中有一个标准系统的.dtprofile文件,dtsourceprofile=true变量位于文件的尾部,CDE使用这个标准文件来产生用户第一次登录到CDE中时放置在home目录的.dtprofile文件。 每当你登录到一个CDE中,都要读这个.dtprofile文件,然后Korn shell读用户的.dtprofile和.kshrc文件。 每当你打开一个控制台窗口,都要再次去读.dtprofile和.kshrc文件,当你在CDE中打开一个终端窗口时,总是要去读.kshrc文件。
| cchmail 回复于:2003-04-05 22:17:04
| 谢谢
| |
|