|
第10章 学习Bash
10.2 BASH 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是GNU计划中重要的工具软件之一,目前也是GNU操作系统中标准的shell,它主要兼容于sh,并依据一些用户需求而加强,可以说目前几乎所有的Linux版本都是使用bash作为管理核心的主要shell。因此,不论您使用的是哪个版本,都必须学习bash。那么这个shell有什么好处,为什么Linux要使用它作为默认的shell呢?BASH主要的优点有下面几个。
命令编辑能力(类似DOS的doskey功能)
bash中个人认为相当棒的一个功能就是它能记忆使用过的指令,您只要在命令行中按上下键就可以找到输入的前一个指令。Mandrake 9.0默认的指令记忆功能可以到达1000个,也就是说,您曾经输入的指令都被记录下来,记录的文件在根目录的.bash_history下。
不过,需要留意的是,~/.bash_history记录的是上一次登入以前执行过的指令,至于这一次登入执行的指令都被暂存在内存中,当您成功注销系统后,该指令记忆才会记录到.bash_history中。这有什么好处呢?最大的好处就是可以查询您曾经有过的动作,知道您的执行步骤,因此可以追踪您曾输入的指令,以备除错之用。但如此一来也有个烦恼,就是如果有黑客入侵,他只要翻查您曾经执行过的指令,而这些指令又跟系统有关(例如直接输入MySQL的密码),那么很容易就能破解您的Linux主机。所以,最好是减少记录的指令数。
补全功能(比对数据正确性)
这个功能也相当棒,主要分为指令补全与文件名称补全。
指令补全:用在执行命令时不想按太多按键的时候。例如指令pcprofiledump够长,如果在输入pcprofile之后按下Tab键,bash马上会自动将后面的dump接上来。如果有重复的指令呢?按下两次Tab将会把所有重复的指令都列出来。这样,直接在提示符后连按两次Tab键,系统会将所有可以使用的指令都列出来。如果我想知道目前系统中所有以b开头的指令,那么按下b之后,连按两次Tab就可以了。
文件名称补全:此外,如果您用vi读取某个文件,例如/etc/man.config,您可以在输入vi /etc/man.之后直接按下Tab键,那么该文件名称会被自动补全。这项功能对于文件名称或者指令名称的正确性方面帮助也很大。所以,有事没事,在bash shell下多按几次Tab键是一个不错的习惯。
命令别名(alias)设定功能
若要知道某个目录下的所有文件(包含隐藏文件)及所有的文件属性,必须输入ls -al这样的指令,这挺麻烦,更快的替代方法是用命令别名。例如我喜欢直接用lm这个自定义命令来取代上面的命令,也就是说,lm等于ls –al。要实现自定义命令可以使用alias,在命令行输入alias就可以知道当前的命令别名都有哪些。也可以直接输入下列命令来设定别名:
alias lm='ls -al'
作业控制、前景背景控制
这部分我们在后面还会提到。使用前、背景控制可以让工作更顺利。作业控制的用途则更广,可以让我们随时将作业放到背景中执行,而不用怕不小心使用了Ctrl + C关掉该程序。此外,还可以在单一登入的环境中达到多任务的目的。
Shell scripts的强大功能
DOS中有将一堆指令写在一起的所谓的“批处理文档”,Linux下的shell scripts则具有更强大的功能,可以将您需要频繁输入的连续指令写成一个文件,该文件通过交互方式进行主机的检测工作。也可以藉由shell提供的环境变量及相关指令编写一个小型的程序语言,这样,以前在DOS下只有程序语言才能写的东西,在Linux下使用简单的shell scripts就可以完成。这部分在后续章节还会详细讲解。
在了解了BASH的优点之后,我们来谈谈如何在Shell环境中输入指令。其实很简单,输入指令的方式为:
[root@test /root]# command [-options] parameter1 parameter2 ...
指令 选项 参数(1) 参数(2)
1. command为指令的名称,例如变换路径的指令为cd
2. 中括号[]并不存在于实际的指令中,在加入参数时,通常为“-”符号,
有时候完整名称会输入“--”符号。例如ls --help
3. parameter1 parameter2为依附在option之后的参数,或者是
command的参数
4. command, -options, parameter1这几项之间以空格分隔,
不论空几格shell都视为一格
5. 指令太长的时候,可以使用 \ 符号来跳转Enter,使指令连续到下一行
实例:
[root@test /root]# ls -al /root
以ls列出/root目录中的隐藏文件与相关的属性参数
[root@test /root]# ls –al /root \> /
上面这两行实际上是一行指令,但是加上 \ 跳转符号后,指令可以连续到下一行。请注意,\字符之后直接按下enter就可以,不可在后面接空格符
[root@test /root]# ls -al /root
这个指令与第一个相同,空格符不论几个,仅视为一个来处理
还有一个问题:Shell什么时候开始接管Linux主机?我们在后面会讲到开机流程,这里先跳过去,假设您的机器已经启动成功,主机进入等待用户登入的状态。当用户输入账号与密码,并且顺利通过之后,经过shell的环境变量文件读取功能,最后,用户进入自己的根目录,例如root的根目录在/root下,一般用户的根目录则在/etc/passwd文件中设定,此时主机已经启动了一个程序bash供您操作。
10.3 变量与变量的设定
继续研究BASH之前,我们先来讨论变量,因为主机中有太多的数据需要存取,而这些数据都是一些服务必须的,例如mail的存取路径/var/spool/mail、默认的根目录/home/useraccount等。我们可以改变这些变量,但是如果该变量已直接深植于套件中,那么修改了某些参数之后,套件必须重新编译源代码。这样很麻烦,所以,就引出了变量。
举个简单的例子,sendmail的smtp存放mail的路径经由/etc/profile中的
MAIL="/var/spool/mail/$USER"
设定,当我修改了上面这一路径,然后重新登入,我的邮件就可以存放到不同的路径,并且可以顺利地在Linux主机上收发。然而问题发生在pop3这个服务上,由于pop3的路径已经硬编码在源代码中,而且正是/var/spool/mail这个路径,也就是说,不论我怎么修改我的“变量”,pop3都不会改变,所以无法直接以pop3收信(例如,OutLook就不能工作了),会发生密码不接受的现象。
此外,我们在执行程序的时候,系统怎么知道您的ls指令放在哪里?这是因为有PATH变量。系统通过这个变量中设定的路径依序寻找该指令系统,如果找不到,屏幕上会显示command not found字样。这些是系统默认的变量,还可以自定义变量,例如您要写一个大型的脚本(批处理文件)时,由于路径在脚本中出现多处,如果换了一台主机,就要修改脚本中的所有路径,后果不堪设想。这时如果使用变量,将变量的定义写在最前面,后面相关的路径名称都以变量取代,那么您只要修改一行就等于修改了整个脚本。所以,良好的程序设计师都会善用变量的定义(这部分我们在下面还会提到)。
从原理上说,在Linux系统中,所有的执行线程都需要一个执行码,就如同上面提到的,您真正以shell跟Linux沟通,是在正确登入Linux之后。这时候您就有一个bash执行程序,真正经由bash跟系统沟通。在进入shell之前,也正如同上面提到的,由于系统需要一些变量来提供数据的存取(或者是一些环境的设定参数值,例如是否显示彩色等),所以就需要一些所谓的环境变量来读入系统中,这些环境变量包括PATH,HOME,MAIL,SHELL等,都很重要。为了与自定义变量区别开来,环境变量通常以大写字符来表示。
说了那么久,到底什么是变量?简单地说,变量就是以一组文字或符号取代一些设定或一串数据,例如,VBird就是鸟哥,所以当您读取VBird的时候,系统自然知道是鸟哥。下面以PATH为例说明,如果您对相对路径与绝对路径还有点印象,那么应该知道要输入正确的指令,应该指定路径与文件名。例如,要输入ls指令,应该指定其路径为/bin/ls,可实际上为什么在任意路径下都可以执行ls而不需要指定路径呢?因为系统已经预设了一些搜寻路径(PATH),需要执行这些指令时,系统会依照该PATH的设定搜寻指令,这个PATH就是所谓的变量。显示变量要用到echo指令。
|
|