Unix/Linux 中的 shell 机制
对于初次接触Unix/Linux系统的同学来说,Unix/Linux系统与Windows系统最大的不同就是,操作Unix/Linux系统更多时候不是使用GUI图形界面而是使用shell命令行。那么,作为Unix/Linux系统的标志性建筑,shell机制究竟是什么呢?
shell是功能强大的命令解释程序,是Unix/Linux系统面向用户的接口界面。但是,shell程序仅仅是操作系统的一部分,是用以与系统内核进行交互的工具,并不是操作系统的核心组成部分。程序员可以根据需要编写符合接口规范的shell程序。
我们分析一下Unix/Linux系统的启动登陆过程,就可以更清楚的了解shell程序在Unix/Linux系统中的地位了。
当Unix/Linux系统启动时,操作系统的内核部分被装入内存,其余部分仍在硬盘上,只有当用户请求执行时才会被加载到内存中。Unix/Linux系统完成启动后,由内核中的init进程激活getty进程,getty进程在相应的终端上显示“login:”提示,等待用户登录。当用户输入用户名时,getty进程读取用户输入并启动login进程,由login进程完成整个登陆过程。用户完成登录后,login进程根据启动配置文件,启动与该登录用户相对应的“默认shell”。此时,shell进程被启动,用户可以通过shell终端与系统内核进行交互。
从Unix/Linux系统的启动过程可以看出,shell程序并非神秘无比,而是一种“长相奇特”的“普通的”、“用以与内核进行交互”的“应用程序”。
各种各样的shell
和Unix/Linux中的其它程序一样,shell也仅仅是一个程序,在Unix/Linux系统中并没有特权。这也是为什么Unix/Linux系统中出现各种各样shell的原因。
1、Bourneshell(sh)。大多数Unix系统的默认安装shell。
2、Kornshell(ksh)。
3、Cshell(csh)。
4、TENEX/TOPSCshell(tcsh)。
5、BourneAgainshell(bash)。大多数Linux系统的默认安装shell。
切换shell
大多数的Unix/Linux系统都提供了多个shell。当系统启动时,由启动配置文件确定启动(默认的)shell,用以用户与系统进行交互。
在RedHat9中,可以通过以下任何一种命令,确定登录用户的默认shell。
cat/etc/passwd#M1
echo$SHELL#M2
在决定要切换shell之前,必须知道系统中安装了哪些shell。在RedHat9中,可以通过以下命令,确定系统中已经安装的各种shell程序。
cat/etc/shells
在我的RedHat9系统中,得到了如下的结果:
/bin/sh
/bin/bash
/sbin/nologin
/bin/bash2
/bin/ash
/bin/bsh
/bin/tcsh
/bin/csh
可以看出来,这其实是一个shell程序文件的列表。一般来说,/bin和/sbin目录都在环境变量PATH中。为了切换为我们喜欢的shell种类,(我们已经知道,shell也仅仅是一种与系统进行交互的程序),我们只需要在命令提示符下输入shell在/bin和/sbin目录中的相应名称即可。
我在使用哪个shell
Unix/Linux系统极少被重新启动,多个对shell有不同爱好的管理员可能操纵过计算机,我们姑且假设他们都使用相同的管理帐号。于是,这就产生了一个问题,我的终端上究竟运行着什么样的shell?
针对这个问题,我在Google上搜寻了一下,有各种各样的答案。有一个回答是
echo$SHELL
我觉得这是不对的,SHELL是环境变量,在整个会话中都不回改变,它表示的是登录用户的“默认shell”。还有人说用
cat/etc/passwd
这样得到的结果也是登录用户的“默认shell”,很显然也不能解决上述问题。
在RedHat9系统上,我用下述方法解决这个问题:
首先,使用命令
echo$$
获得当前shell进程的PID。我在测试中,得到的结果是10650。
然后,使用命令
ps-A|grep10650
获取进程列表,并进行筛选。得到这样的测试结果:
10650pts/000:00:00csh
于是得到的结论是,测试中使用的shell是csh。