什么是 shell
Java
Asp
PHP
.Net
XML
C/C++
CGI
VB
Jsp
J2ee
J2se
J2me
EJB
Servlet
Tomcat
Resin
Struts
Weblogic
Eclipse
ANT
GUI
JMS
Web servise
IDEA
Webphere
Hibernate
Spring
Jboss
Applet
Swing
Socket
Javamail
Perl
Ajax
P2P
安全
模式
框架
测试
开源
游戏
Windows XP
Windows 2000
Windows 2003
Windows Me
Windows 9.x
Linux
UNIX
注册表
操作系统
服务器
应用服务器
这应该是个蛮有趣的话题:『什么是 shell ?』相信只要摸过电脑,对于作业系统(不论是 linux 、 unix 或者是 windows )有点概念的朋友们大多听过这个名词,因为只要有『作业系统』那么就离不开 shell 这个东西。不过,在讨论 shell 之前,我们先来了解一下电脑的运作状况吧!举个例子来说:当你要电脑传输出来『音乐』的时候,你的电脑需要什么东西呢?
1. 当然就是需要你的硬体有『音效卡晶片』这个硬体配备,否则怎么会有声音;
2. 作业系统的核心可以支援这个晶片组,当然还需要提供晶片的驱动程式啰;
3. 需要使用者(就是你)输入发生声音的指令啰!
这就是基本的一个输出声音的需要的步骤!那么也就是说,你必须要『输入』一个指令之后,『硬体』才会透过你下达的指令来工作!嘿嘿!那么硬体如何知道你下达的指令呢?那就是 kernel (核心)的控制工作了!了解了吗?没错!也就是说,我们必须要透过『 shell 』将我们输入的指令与 kernel 沟通,好让 kernel 可以控制硬体来正确无误的工作!基本上,我们可以透过底下这两张图来说明一下:
基本上,替我们工作的是『硬体』,而控制硬体的是『核心』,再来,我们使用者乃是利用『shell』控制一些 kernel 提供的 『工具 utility』来操控硬体替我们正确的工作。再举个例子来说,当我们使用 shell 的功能,输入『 cd /』来切换目录时, shell 便利用 kernel 提供的 cd 工具来告诉 kernel 转换硬碟的工作目录到 / 当中,然后硬碟就根据 kernel 的掌控而切换到 / 当中啰!这个就是 shell 的主要功能啰!再进一步来说,由于 kernel 听不懂人类的语言,而人类也没有办法直接记得 kernel 的语言,所以两者的沟通就得藉由 shell 来支援了!
以字面上的意思来说, kernel 是『核心』的意思,而 shell 是『壳』的意思,呵呵!也就是说, shell 是最外头的咚咚!而 kernel 乃是最内层的的咚咚啦!核心是作业系统的最底层的东西!这个核心里头包括了各种的支援硬体的工具!当然啰,如果你的硬体太新,而你的 kernel 并没有支援的话,那么很抱歉,你的 shell 能力再怎么强,也没有办法使硬体工作的!这样可以了解了吗?呵呵!没错!使电脑主机工作的正是核心的任务,但是操作核心来替使用者工作的,却是 shell 喔!因此,有时候你的 shell 搞了老半天,硬体却不能工作的时候,请注意,您的『核心』是否正确呢?阿!扯远了!这是 kernel 章节才要说的东西~~
bash shell
知道什么是 shell 之后,那么我们来了解一下 linux 使用的是哪一个 shell 呢?什么!哪一个?难道说 shell 不就是『一个 shell 吗?』哈哈!那可不!由于早年的 unix 年代,发展者众,呵呵!所以由于 shell 依据发展者的不同就有许多的版本,例如常听到的 bourne shell (sh) 、在 sun 里头预设的 c shell、 商业上常用的 k shell、, 还有 tcsh 等等,每一种 shell 都各有其特点。至于 linux 使用的这一种版本就称为『 bourne again shell (简称 bash ) 』,这个 shell 是 bourne shell 的增强版本,也是基准于 gnu 的架构下发展出来的呦!
在介绍 shell 的优点之前,先来说一说 shell 的简单历史吧:第一个流行的 shell 是由 steven bourne 发展出来的,为了纪念他所以就称为 bourne shell ,或直接简称为 sh !而后来另一个广为流传的 shell 是由柏克莱大学的 bill joy 设计依附于 bsd 版的 unix 系统中的 shell ,这个 shell 的语法有点类似 c 语言,所以才得名为 c shell ,简称为 csh !由于在学术界 sun 主机势力相当的庞大,而 sun 主要是 bsd 的分支之一,所以 c shell 也是另一个很重要而且流传很广的 shell 之一(因为太多的程式设计师使用的就是 c 语言啦!)!
好了,那么 bash 是怎么一回事呢?这个 shell 是 gnu 计画中重要的工具软体之一,目前也是 gnu 作业系统中标准的 shell ,他主要相容于 sh 。所以,可想而知的,目前几乎所有的 linux distribution 都是使用 bash 作为管理核心的主要 shell 啰!那么这个 shell 有什么好处,干嘛 linux 要使用他作为预设的 shell 呢? bash 主要的优点有底下几个:
· 命令编修能力(类似 dos 的 doskey 功能):使用 bash 里头,个人认为相当棒的一个功能就是『他能记忆使用过的指令!』这功能真的相当的棒!因为我只要在指令列按『上下键』就可以找到前一个输入的指令!而预设的指令记忆功能可以到达 1000 个!也就是说,你曾经下达过的指令都被记录下来了,记录的档案在你的家目录内的 .bash_history !至于这一次登入所执行的指令都被暂存在暂存区中,成功的登出系统后,该指令记忆才会记录到 .bash_history 当中!这有什么功能呢?最大的好处就是可以『查询曾经做过的举动!』,如此可以知道你的执行步骤,那么就可以追踪您曾下达的指令,以作为除错的工具!但如此一来也有个烦恼,就是如果被骇客入侵了,那么他只要翻你曾经执行过的指令,刚好你的指令又跟系统有关(例如直接输入 mysql 的密码在指令列上面)那么很容易就被破解你的 linux 主机!所以,最好是将记录的指令数目减小一点较好!
·档案比对补全功能(比对资料正确性):这个功能也相当的棒!如果在执行命令的时候不想按下太多的按键,例如指令 pcprofiledump 够长吧!好了,那么如果你输入了 pcprofile 之后,再按下 [tab] 按键的话,那么 bash 马上会自动的将后面的 dump 接上来!那如果有重复的指令呢?那么按下两次 [tab] 将会把所有重复的指令给他列出来啰!
o直接在指令列按下 [tab][tab] 两次,那么 linux 将会把系统内的所有执行档列出来;
另外一个优点就是,可以将该指令所进行的 parameter (与路径或档案相关的)比对后,列出正确的项目!举个例子来说,如果我要列出 /etc/sysconfig.network-scripts 里面的所有档案时,要如何下达参数?
o ls -al /etc/sysconfig.network-scripts
那我可以在输入到.network 时按下 [tab] 按键,则 -scripts 就会被自动的加入命令列了!反正真的是蛮方便的,有事没事多按[tab] 按键是不错的一件事呦!
·命令别名(alias)设定功能:假如我需要知道这个目录底下的所有档案(包含隐藏档)及所有的档案属性,那么我就必须要下达 ls -al 这样的指令列,唉!真麻烦,有没有更快的取代方式?呵呵!就使用命令别名呀!例如我最喜欢直接以 lm 来取代上面的命令,也就是说, lm 会等于 ls -al 这样的一个功能,嘿!那么要如何作呢?就使用 alias 即可!你可以在指令列出入 alias 就可以知道目前的命令别名有哪些了!也可以直接下达命令来设定别名呦:
oalias lm='ls -al'
·工作控制 (jobs)、前景背景控制:这部分我们在之后的 指令篇会再提及!使用前、背景的控制可以让工作进行的更为顺利!至于工作控制(jobs)的用途则更广,可以让我们随时将工作丢到背景中执行!而不怕不小心使用了 [ctrl] + c 来停掉该程序!真是好样的!
·shell scripts 的强大功能:在 dos 年代还记得将一堆指令写在一起的所谓的『批次档』吧?在 linux 底下的 shell scripts 则发挥的更为强大的功能,可以将您日常生活当中常需要下达的连续指令写成一个档案,该档案并且可以透过对谈互动式的方式来进行主机的侦测工作!也可以藉由 shell 提供的环境变数及相关指令来进行设计,哇!整个设计下来几乎就是一个小型的程式语言了!该 scripts 的功能真的是超乎我的想象之外!以前在 dos 底下需要程式语言才能写的东西,在 linux 底下使用简单的 shell scripts 就可以帮你达成了!真的利害!!这部分我们在底下再来谈!
在了解了 bash 的优点之后,再来我们要来讨论的是:那如何在 shell 提供的环境中下达指令呢?其实很简单的,下达指令的方式为:
很简单吧!ok!那么再来一个问题:『shell 是什么时候开始接管 linux 主机的!?』如果您对于鸟哥前面提到的『开机流程』有稍微去了解一下的话,那么应该可以了解到 linux 经由 kernel 执行完毕,并且执行了 init 与 run-level 设定的一些 scripts 之后,接下来执行了 login 的程式,就可以顺利的进入到 shell 接管的程序了!当然啰,要等到使用者顺利的登入 linux 之后,才可以使用 shell 来进行与主机沟通的动作呦!另外,需要注意的是,登入主机之后通常使用者的起始目录会在『家目录』, root 的家目录预设在 /root 底下,一般使用者的家目录则与 /etc/passwd 的设定有关!
变数与变数的设定:echo, env, set, 变数设定规则, export, unset,
再继续研究 bash 之前,我们要就变数这个东西来讨论一番,因为在主机里面有太多的资料需要进行存取了,而这些资料都是一些服务所必须的,例如 mail 的存取路径在 /var/spool/mail 、家目录预设在 /home/useraccount 等等,当然我们可以改变这些个变数,但是如果该变数是直接深植于套件当中,那么当你修改了某些参数之后,嘿嘿!你的套件就必须要『由原始码直接更新再编译』才行!这样似乎很麻烦,所以啰,就会有变数这个好东西出来了!
举个简单的例子来说, sendmail 的 smtp 存放 mail 路径是经由 /etc/profile 里头的 mail="/var/spool/mail/$user"来设定的,而当我修改了上面这一个咚咚,然后重新开机之后,嘿嘿嘿嘿!我的邮件就可以存放到不同的路径去了!而且不会有问题!可以顺利的『在 linux 主机上面』收发。然而问题发生在 pop3 这个服务上面,由于 pop3 的预设路径是在 source code 里头,而且就正是 /var/spool/mail 这个路径,也就是说,不论我怎么修正我的『变数』, pop3 都不为所动!唉~真惨,所以就无法直接以 pop3 来收信了(例如 outlook 就不能工作了)!会发生密码不接受的问题呢!
此外,例如我们在执行程式的时候,系统怎么知道你的 ls 这个指令放在哪里?原来是有 path 这个变数,系统会透过这个变数里面所设定的路径去依序寻找该指令系统,如果找不到的话,那么才在萤幕上显示『 command not found 』字样!这些还都只是系统预设的变数的目的,如果是个人的设定方面:例如你要写一个大型的 script (批次档)时,有些资料因为可能由于使用者习惯的不同而有差异(例如路径!),而由于该内容使用在 script 的地方相当的多,如果每次都需要修改该地方,则一定会疯掉!这个时候使用变数,而将该变数的定义写在最前面,嘿嘿!那么你只要修改一行就等于修改整篇 script 了!方便的很!所以,良好的程式设计师都会善用变数的定义!(这个部分我们在底下还会再提到!)
如果说的学理一点,那么由于在 linux system 下面,所有的执行续都是需要一个执行码,而就如同上面提到的,你『真正以 shell 来跟 linux 沟通,是在正确的登入 linux 之后!』这个时候你就有一个 bash 的执行程序,也才可以真正的经由 bash 来跟系统沟通啰!而在进入 shell 之前,也正如同上面提到的,由于系统需要一些变数来提供他资料的存取(或者是一些环境的设定参数值,例如是否要显示彩色等等的),所以就有一些所谓的『环境变数』需要来读入系统中了!
说了那么久,那么到底『什么是变数』呢?简单的说,『变数就是以一组文字或符号等,来取代一些设定或者是一串保留的资料!』,例如:『vbird』就是『鸟哥』,所以当你读取 vbird 的时候,系统自然就会知道!哈!那就是鸟哥!最简单的例子可以取 path 来说明!如果你对于『相对路径与绝对路径』还有点印象的话,那么应该晓得『要下达正确的指令,应该需要指定路径与档名』才行!例如你的 ls 指令应该需要以『/bin/ls』来下达指令才对,那么为何你在任意的路径下都可以执行 ls 呢?而不需要指定路径呢?这是因为系统已经预设了一些『搜寻路径(path)』了,所以当你需要执行一些指令的时候,系统就会依照该 path 的设定来进行指令的搜寻!而这个 path 就是所谓的变数了!那么如何『显示变数』呢?这就需要使用到 echo 这个指令啦!
·echo
显示变数内容
语法:
就如同上面的范例,当我们要显示目前的 path 这个变数时,使用了 echo ,而为了要分辨是否为变数,那么 linux 系统预设变数名称前面会加上一个『 $ 』符号,所以就必须要写成 echo $path 啰!
·有多少的环境变数呀?使用 env 与 set 来看看:
这是我们比较有兴趣的,那就是有多少的环境变数在 linux 系统中呢?呵呵!你可以简单的使用 env 就可以知道啰!『基本上,在 linux 预设的情况中,使用{大写的字母}来设定的变数一般为系统内定需要的变数』,底下列出 red hat 7.2 预设的变数内容:
·env
显示目前系统中主要的预设变数内容
语法:
env 这个指令主要在将目前系统中的主要变数读出来!但是我加上了 sort 就可以将资料进行排序啰!所以像上面的 path, user, home 等等的资料就会被读出来啰!除了 env 这个指令之外,还有一个可以将目前系统中所有的变数资料都读出来的指令,称为 set !set 除了会将上面的资料都给他读出来之外,还会有额外的这些资讯也一起读入(通常都与使用者的设定有关!):
·set
显示目前系统中全部的变数内容
语法:
使用 set 除了会将系统的预设值秀出来之外,连带的所有的你自己设定的变数也会被秀出来!同时需要注意的是,若当时有相当多人同时在线上的话,那么你的变数只能给自己使用(除非改的是系统的预设参数档,如 /etc/profile ),而不会干扰到别人的!就如同前面所说的,由于你登入 linux 之后会取得一个 pid ,而你的设定将只对这个 pid 与子程序有关!此外,这次登入所进行的变数设定,如果没有更动到设定档,那么这次设定的变数在下次登入时将被取消掉(因为程序 pid 不见啰!)!所以啰,如果你想要你的变数每次都能在你登入的时候自动就设定好了,那么就必须将你的设定写入登入时载入的设定档!
· 变数设定规则:
好了,我们知道了一些系统的预设变数了,但是如果是我自己想要设定一些我自己的变数,该如何设定呢?有什么规则需要遵守?呵呵!在说明之前,可能要来让大家了解一下为什么自己会想来设定变数?
我的案例一:最简单的例子就是『路径名称』啰!以鸟哥为例,我的工作在 unix 系统之下进行一些数值模式的模拟工作,偏偏由于资料量太大,为了怕日后忘记这个目录的内容与主要的意义,所以我的档名都取的很长,偏偏在执行模式的过程中,常常会切换目录!我哩ㄌㄟ,光是打那几行路径名称就快要疯掉了!所以我就设定那几行目录名称成为一个四个字元的变数,如此一来我只要输入『 cd $vari 』这个指令,嘿嘿!马上就移动到该路径下了!很方便吧!当然变数的意义还不止于此,不过这是最简单的实例说明啰!
关键字 本文所属关键字
相关 与本文相关文章
分类 所有文章关键字导航
源码编程相关
操作系统/服务器相关
标准 网站致力的规范