在介绍 shell 是甚么东西之前,不妨让我们重新检视使用者与计算机系统的关系,我们知道计算机的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱动只能透过一个称为"操作系统(Operating System)"的软件来控管,事实上,我们每天所谈的 freebsd、netbsd、openbsd、 linux等等 ,严格来说只是一个操作系统,我们称之为"核心(kernel)"。然而,从使用者的角度来说,使用者也没办法直接操作 kernel ,而是透过 kernel 的"外壳"程序,也就是所谓的shell ,来与 kernel 沟通。从技术角度来说,shell是一个使用者与系统的互动界面(interface),主要是让使用者透过命令行(command line)来使用系统以完成工作。因此,shell 的最简单的定义就是---命令解译器(Command Interpreter):
* 将使用者的命令翻译给核心处理,
* 同时,将核心处理结果翻译给使用者。
每次当我们完成系统登入(login),我们就取得一个互动模式的shell ,也称为 login shell 或 primary shell。若从进程(process)角度来说,我们在 shell 所下达的命令,均是 shell 所产生的子进程。这现象,我们暂可称之为fork。 如果是执行脚本(shell script)的话,脚本中的命令则是由另外一个非互动模式的子 shell (sub shell)来执行的。也就是primary shell 产生 sub shell 的进程,sub shell 再产生 script 中所有命令的进程。
FreeBSD的基本系统中可以使用的shell有两个:sh和csh。这两个基本shell的风格不太相同,不同的使用者常常会根据喜好来在两者之间进行选择。当然当前有更好的shell程序可供使用者选择,这些后续的 shell均是根据sh或csh的风格进一步发展出的,因此可以说在shell中,也有两种风格,需要使用者根据自己的使用习惯进行选择。
在默认安装下,FreeBSD支持sh、csh、tsch,从/etc/shells中可以看出。
命令提示符补充一下:
如果shell是sh,则提示符为“$”,如果shell是csh,则为“%”,需要注意的是如果是root用户,则提示符为“#”。
sh和csh又有以下不同的分支:
Bourne shell :
burne shell (sh)
burne again shell (bash)
korn shell (ksh)
POSIX shell ( sh) C shell :
c shell (csh)
TENEX/TOPS C shell ( tcsh)
C Shell Bill Joy于20世纪80年代早期,在Berkeley的加利福尼亚大学开发了C shell。它主要是为了让用户更容易的使用交互式功能,并把ALGOL风格的语法结构变成了C语言风格。它新增了命令历史、别名、文件名替换、作业控制等功能。
有很长一段时间,只有两类shell供人们选择,Bourne shell用来编程,C shell用来交互。为了改变这种状况,AT&T的bell实验室David Korn开发了Korn shell。ksh结合了所有的C shell的交互式特性,并融入了Bourne shell的语法。因此,Korn shell广受用户的欢迎。它还新增了数学计算,进程协作(coprocess)、行内编辑(inline editing)等功能。Korn Shell 是一个交互式的命令解释器和命令编程语言.它符合POSIX——一个操作系统的国际标准.POSIX不是一个操作系统,而是一个目标在于应用程序的移植性的标准——在源程序一级跨越多种平台。
bash是GNU计划的一部分,用来替代Bourne shell。它用于基于GNU的系统如Linux.大多数的Linux(Red Hat, Slackware, Caldera)都以bash作为缺省的shell,并且运行sh时,其实调用的是bash。
POSIX shell 是Korn shell的一个变种. 当前提供POSIX shell的最大卖主是Hewlett-Packard。在HP-UX 11.0 , POSIX shell 就是/bin/sh,而bsh是/usr/old/bin/sh.
各主要操作系统下缺省的shell: AIX 下是Korn Shell. Solaris和FreeBSD缺省的是Bourne shell. HP-UX缺省的是POSIX shell. Linux是Bourne Again shell
输入命令echo $SHELL可查看你用的是什么shell,也可以根据提示符来看,如果shell是sh,则提示符为“$”,如果shell是csh,则为“%”,需要注意的是如果是root用户,则提示符为“#”。
对于管理员来将,要为使用不同shell的用户都设置好基本的环境,就必须了解这两种风格的shell设置方式。
系统登录时,sh将首先执行/etc/profile文件,为每个用户设置最基本的环境,而csh将使用/etc/csh.cshrc,csh.login和csh.logout作为系统csh资源文件。
执行了系统级别的登录文件之后,每个用户的shell就在该用户的主目录下寻找该用户个人的资源文件:sh使用.profile文件,csh使用.login和.cshrc文件。这些资源文件均使用相应的shell语言,/etc/profile和个人目录下的.profile使用sh风格的控制语言,/etc/cshrc和个人目录下的.login、.cshrc使用csh 风格的控制语言。
系统管理员可以改动这些资源文件,为用户提供一个最方便的使用环境。当然,系统管理员没有必要直接去修改个人主目录下的资源文件,这些文件应该由用户自己管理,但是系统管理员可以在生成帐号时为用户产生缺省的资源文件,以减轻用户设置资源文件的麻烦。adduser命令缺省使用/usr/share/skel下的文件为用户提供各种资源文件的缺省设置,这个目录下除了可以放入shell的资源文件之外,还可以放入其他应用程序的资源文件。由于这些资源文件都是以点开头的隐藏文件,为了表示清楚,在skel目录下使用了一种转换方式,如使用dot.profile 作为.profile的模板。
dot.cshrc dot.login_conf dot.mailrc dot.rhosts
dot.login dot.mail_aliases dot.profile dot.shrc
在/usr/share/skel中为用户设置的缺省配置文件,在用户生成之后,就不会对用户产生影响了。因此对系统登录文件进行修改更有效和直接。对于sh风格的用户,可以更改/etc/profile文件,对csh应更改/etc/csh.cshrc文件。在这些文件中可以改动shell使用的环境变量,这样来改变shell的行为方式,或者执行一系列自动操作,完成一些用户登录时需要自动执行的任务。
常用的环境变量:
EDITOR 设置用户常用的编辑器,很多程序查看这个变量来启动具体的编辑器,可以 根据系统的情况更改
HOME 用户的主目录的名字,这个变量由login程序设置,一般不需要更改
DISPLAYX 使用这个环境变量来标识具体的显示位置,格式为“计算机名字:X服务 器序号.显示屏序号” ,例如:xt1:0.0,它不需要在资源文件中进行定义
LANG 系统使用的语言,用于系统的本地化,缺省为 “C” ,具体的设置可以查看 /usr/share/locale 目录,那里定义了不同的语言,可以将其设置为zh_CN.EUC来使得一些软件使用中文字符。
MAIL 用户mail文件的位置,也不需要改动
PATH 使用冒号分隔的一系列路径,系统用它来查找具体可执行程序,因此这个变量非常重要,可以根据具体的情况改动其值。为了安全的原因,不要将当前目录作为执行程序的搜寻路径,尤其对于root用户。这样在当前目录下启动程序,需要加上路径,例如启动当前目录下的a.out 程序,输入 “./a.out” 。
MANPATH 使用冒号分隔的一系列路径,系统用它来查找具体命令的在线手册,设置方法与PATH相同。
PS1sh 风格的shell使用这个变量的值作为提示符,缺省值为 “$”(root为 “#” )。更现代的sh就增强了提示符的灵活性,可以在提示符中加入当前目录、用户名、机器名,命令的序号等。
PS2sh 风格的shell使用这个变量的值作为后续提示符,提示命令还没有完全输入,缺省为 “>;“
TERM 终端的类型,对于需要全屏操作的程序,非常重要。有时要根据情况对设置进行调整。
TZ 时区设置,具体的时区信息位于/usr/share/zoneinfo目录下,需要设置为适合本地时区的标准值
可以将用户的shell设置为特殊的应用程序,来达到对特殊用户进行限制的目的。例如,仅仅给予用户一个电子邮件信箱,但不想给他终端使用权,可以将用户的 shell更改为/bin/true或者其他立即退出的程序。为了安全起见,用户shell应该是一个不存在漏洞的二进制程序,最好不要使用解释性语言脚本作为登录shell。由于系统认可的shell程序是在/etc/shells文件中列出的程序,将特殊用户的shell设置为特殊的应用程序,但这些应用程序没有列入shells文件,那么这个用户就会被一些应用程序区分出与普通用户的差异,从而拒绝提供服务。例如ftp服务器程序ftpd,通过检查用户的shell是不是标准shell,来区分这个用户是普通用户还是用于特定目的的用户。
例如通过源代码编译安装mysql的时候,需要首先建立一个mysql用户,该用户我们不希望他可以登录系统,因此把它的shell设置为/nonexistent:
pw useradd mysql -g mysql -s /nonexistent