学习1bash shell

46 篇文章 0 订阅
认识 BASH Shell
最近更新日期:2003/02/10
什么是 Shell
BASH Shell
变量与变量的设定echo,env, set, 变量设定规则, export, unset, 变量的有效范围, read, array, $RANDOM, eval, 重要的环境变量(?, HOME, SHELL, MAIL, HISTSIZE...)
命令别名与历史命令alias(设定命令别名),history, !command,
bash shell 的设定档案source,
万用字符与特殊符号
绝对路径与相对路径
命令重导向 ( redirect )
管线命令 ( pipe ) cut, sort, wc, uniq, tee, tr, split,
本章习题练习

什么是 Shell
这应该是个蛮有趣的话题:『 什么是 Shell ?』相信只要摸过计算机,对于操作系统(不论是 Linux 、 Unix 或者是 Windows )有点概念的朋友们大多听过这个名词,因为只要有『操作系统』那么就离不开 Shell 这个东西。不过,在讨论 Shell 之前,我们先来了解一下计算机的运作状况吧!举个例子来说: 当你要计算机传输出来『音乐』的时候,你的计算机需要什么东西呢
  1. 当然就是需要你的硬件有『声卡芯片』这个硬件配备,否则怎么会有声音;
  2. 操作系统的核心可以支持这个芯片组,当然还需要提供芯片的驱动程序啰;
  3. 需要使用者(就是你)输入发生声音的指令啰!
这就是基本的一个输出声音的需要的步骤!那么也就是说,你必须要『输入』一个指令之后,『硬件』才会透过你下达的指令来工作!嘿嘿!那么硬件如何知道你下达的指令呢?那就是 kernel (核心)的控制工作了!了解了吗?没错!也就是说, 我们必须要透过『 Shell 』将我们输入的指令与 Kernel 沟通,好让 Kernel 可以控制硬件来正确无误的工作!基本上,我们可以透过底下这两张图来说明一下:

基本上,替我们工作的是『硬件』,而控制硬件的是『核心』,再来,我们使用者乃是利用『Shell』控制一些 kernel 提供的 『工具 Utility』来操控硬件替我们正确的工作。再进一步来说,由于 kernel 听不懂人类的语言,而人类也没有办法直接记得 kernel 的语言,所以两者的沟通就得藉由 shell 来支援了!(其实早期的 DOS 的文字接口也是使用 shell 来沟通呀!那个 shell 的名称就叫做 command.com ,还记得吗? ^_^)
 
以字面上的意思来说, kernel 是『核心』的意思,而 Shell 是『壳』的意思,呵呵!也就是说, shell 是最外头的咚咚!而 kernel 乃是最内层的的咚咚啦!核心是操作系统的最底层的东西!这个核心里头包括了各种的支持硬件的工具!当然啰,如果你的硬件太新,而你的 kernel 并没有支持的话,那么很抱歉,你的 Shell 能力再怎么强,也没有办法使硬件工作的!这样可以了解了吗?呵呵!没错!使计算机主机工作的正是核心的任务,但是操作核心来替使用者工作的,却是 shell 喔!因此,有时候你的 shell 搞了老半天,硬件却不能工作的时候,请注意,您的『核心』是否正确呢?阿!扯远了!这是 kernel 章节才要说的东西??
  • 我干嘛要学习 Shell 呢?
    常常听到这个问题:『我干嘛要学习 shell 呢?不是已经有很多的工具可以提供我设定我的主机了?我为何要花这么多时间去学指令呢?不是以 X-Window 按一按几个按钮就可以搞定了吗?为什么要这么麻烦?』唉?还是得一再地强调,X-Window 还有 Web 接口的设定工具例如 webmin 是真的好用的家伙,他真的可以帮助我们很简易的设定好我们的主机,甚至是一些很进阶的设定都可以帮我们搞定。但是 VBird 在序章里面也已经提到过相当多次了, X-Window 的接口虽然亲善,功能虽然强大,而 web 接口的工具也可以提供我们很友善的服务,但是毕竟他是整合的一个套件而已,并非是一个完整的套件,所以某些时候当你升级或者是使用其它套件管理模块( 例如 tarball 而非 rpm 档案等等 )时,就会造成设定的困扰了,此外,远程联机时,文字接口的传输速度一定比较快,而且,较不容易出现断线或者是信息外流的问题,因此, shell 真的是得学习的一项工具。而且,他可以让您更深入 Linux ,更了解他,而不是只会按一按鼠标而已!所谓『天助自助者!』多摸一点文字模式的东西,会让你与 Linux 更亲近呢!
     
    有些朋友也很可爱,常会说:『我学这么多干什么?又不常用,也用不到!』嘿嘿!有没有听过『书到用时方恨少?』当你的主机一切安然无恙的时候,您当然会觉得好像学这么多的东西一点帮助也没有呀!万一,某一天真的不幸给他中标了,您该如何是好?是直接重新安装?还是先追踪入侵来源后进行漏洞的修补?或者是干脆就关站好了?这当然涉及很多的考虑,但就以 VBird 的观点来看,多学一点总是好的,尤其我们可以有备而无患嘛!甚至学的不精也没有关系,了解概念也就 OK 啦!毕竟没有人要您一定要被这么多的内容啦!了解概念就很了不起了!
     
    此外,如果您真的有心想要将您的主机管理的好,那么良好的 shell 程序编写是一定需要的啦!就 VBird 来说,我管理的主机虽然还不算多,只有区区不到十部,但是如果每部主机都要花上几十分钟来查阅他的 log file 以及相关的信息,那么我可能会疯掉!基本上,也太没有效率了!这个时候,如果能够藉由 shell 提供的命令重导向( 或称数据流重导向 ),以及管线命令,呵呵!那么我分析 log file 只要花费不到十分钟就可以看完所有的主机之重要信息了!相当的好用呢!
     
    由于学习 shell 的好处真的是多多啦!所以,如果您是个系统管理员,或者有心想要管理系统的话,那么 shell 这个东西与 shell scripts 这个东西,真的真的有必要看一看!

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 ,并且依据一些使用者需求,而加强的 shell 版本,可以说目前几乎所有的 Linux distribution 都是使用 bash 作为管理核心的主要 shell !因此,不论您使用的是那个 distribution ,你都难逃需要学习 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'
  • 工作控制(jobs)、前景背景控制:
    这部分我们在之后的资源管理章节中会再提及!使用前、背景的控制可以让工作进行的更为顺利!至于工作控制(jobs)的用途则更广,可以让我们随时将工作丢到背景中执行!而不怕不小心使用了 [Ctrl] + C 来停掉该程序!真是好样的!此外,也可以在单一登入的环境中,达到多任务的目的呢!
  • Shell scripts 的强大功能:
    在 DOS 年代还记得将一堆指令写在一起的所谓的『批次档』吧?在 Linux 底下的 shell scripts 则发挥的更为强大的功能,可以将您日常生活当中常需要下达的连续指令写成一个档案,该档案并且可以透过对谈交互式的方式来进行主机的侦测工作!也可以藉由 shell 提供的环境变量及相关指令来进行设计,哇!整个设计下来几乎就是一个小型的程序语言了!该 scripts 的功能真的是超乎我的想象之外!以前在 DOS 底下需要程序语言才能写的东西,在 Linux 底下使用简单的 shell scripts 就可以帮你达成了!真的利害!!这部分我们在后续章节再来谈!
在了解了 BASH 的优点之后,再来我们要来讨论的是: 那如何在 Shell 提供的环境中下达指令呢 ?其实很简单的,下达指令的方式为:
[root@test /root]#command [-options] parameter1 parameter2 ...
                     指令     选项      参数(1)    参数(2)

1. command 为指令的名称,例如变换路径的指令为 cd 等等;
2. 中刮号[]并不存在于实际的指令中,而加入参数设定时,通常为 - 号,有时候完整名称会输入 -- 符号;
3. parameter1 parameter2.. 为依附在 option 后面的参数,或者是 command 的参数;
4. command, -options, parameter1.. 这几个咚咚中间以空格来区分,不论空几格 shell 都视为一格;
5. 指令太长的时候,可以使用 \ 符号来跳脱 [Enter] 符号,使指令连续到下一行。

实例:
[root@test /root]#ls -al /root   <==以 ls 列出 /root 这个目录中的隐藏文件与相关的属性参数;
[root@test /root]#./configure --prefix=/usr/local --with-tcp_wrappers \
> --with-pam     <==这两行实际上是同一行的指令,但是加上 \ 跳脱符号后,指令可以连续到下一行!
[root@test /root]# ls           -al   /root <==这个指令与第一个相同,空格符不论几个,仅视为一个来处理。

很简单吧!OK!那么再来一个问题:『 Shell 是什么时候开始接管 Linux 主机的!?』我们在后面会再提到『 开机流程』的介绍,这里先跳过去,假设你的机器已经开机成功了,那么主机便进入等待使用者 login 的状态。当使用者输入了账号与密码,并且顺利的 pass 之后,经过了 shell 的环境变量档案读取功能,最后,使用者进入自己的『家目录』之后,例如 root 的家目录在 /root 底下,一般使用者的家目录则在 /etc/passwd 这个档案里面规定,那么主机就已经丢了一个程序称为 bash 的给你操作啰!

变量与变量的设定: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 里面的所有路径,那么我一定会疯掉!这个时候如果使用变量,而将该变量的定义写在最前面,后面相关的路径名称都以变量来取代,嘿嘿!那么你只要修改一行就等于修改整篇 script 了!方便的很!所以,良好的程序设计师都会善用变量的定义!(这个部分我们在底下还会再提到!)
 
如果说的学理一点,那么由于在 Linux System 下面,所有的执行续都是需要一个执行码,而就如同上面提到的,你『 真正以 shell 来跟 Linux 沟通,是在正确的登入 Linux 之后!』这个时候你就有一个 bash 的执行程序,也才可以真正的经由 bash 来跟系统沟通啰!而在进入 shell 之前,也正如同上面提到的,由于系统需要一些变量来提供他数据的存取(或者是一些环境的设定参数值,例如是否要显示彩色等等的),所以就有一些所谓的『 环境变量』需要来读入系统中了!这些环境变量例如 PATH、HOME、MAIL、SHELL等等,都是很重要的,为了区别与自订变量的不同,环境变量通常以大写字符来表示呢!
 
说了那么久,那么到底『 什么是变量』呢?简单的说,『 变量就是以一组文字或符号等,来取代一些设定或者是一串保留的数据!』,例如:『VBird』就是『鸟哥』,所以当你读取 VBird 的时候,系统自然就会知道!哈!那就是鸟哥!最简单的例子可以取 PATH 来说明!如果你对于『 相对路径与绝对路径』还有点印象的话,那么应该晓得『 要下达正确的指令,应该需要指定路径与文件名』才行!例如你的 ls 指令应该需要以『/bin/ls』来下达指令才对,那么为何你在任意的路径下都可以执行 ls 呢?而不需要指定路径呢?这是因为系统已经预设了一些『 搜寻路径(PATH)』了,所以当你需要执行一些指令的时候,系统就会依照该 PATH 的设定来进行指令的搜寻!而这个 PATH 就是所谓的变量了!那么 如何『显示变量』呢?这就需要使用到 echo 这个指令啦!

  • echo
    显示变量内容

    语法
    [test @test test]# echo $variable
    参数说明:
    范例:
    [test @test test]#echo $PATH
    /bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/loc
    al/bin:/bin:/usr/bin:/usr/X11R6/bin
    就如同上面的范例,当我们要显示目前的 PATH 这个变量时,使用了 echo ,而为了要分辨是否为变量,那么 Linux 系统预设变量名称前面会加上一个『 $ 』符号,所以就必须要写成 echo $PATH 啰!
    例题:请在屏幕上面显示出您的环境变量 PATH, HOME 与 MAIL:
    答:
    [root@test root]# echo $PATH
    /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
    [root@test root]# echo $HOME
    /root
    [root@test root]# echo $MAIL
    /var/spool/mail/root


    有多少的环境变量呀?使用 env 与 set 来看看:
    嗯!既然环境变量是挺重要的,那么到底有多少的环境变量在 Linux 系统中呢?呵呵!你可以简单的使用 env 就可以知道啰!『基本上,在 Linux 预设的情况中,使用{大写的字母}来设定的变量一般为系统内定需要的变量』,底下列出 Linux 系统中 预设的变量内容:

  • env
    显示目前系统中主要的预设变量内容

    语法
    [test @test test]#env
    ENV=/root/.bashrc             <==使用者自订环境变量的设定档案
    HISTSIZE=1000                 <==目前的指令记忆数量
    HOME=/home/test               <==登入者的家目录
    HOSTNAME=test.adsldns.org <==这部主机的主机名称
    HOSTTYPE=i386             <==这部主机的硬件等级大致状态(i386, i686..)
    INPUTRC=/etc/inputrc          <==一些 shell 加载的数据文件设定处
    LANGUAGE=C                    <==预设语系的资料
    LANG=zh_TW.Big5 
    与 LANGUAGE 类似,这个则是各个 linux distribution 常用的预设语系变量,由于我的 Mandrake 使用中文安装,所以预设语系是中文,亦即 zh_TW.Big5 ,如果我要修改这个变量,可以到 /etc/sysconfig/i18n 去修改!底下的 LC_xxx 均是与预设的表示语系有关的变量,其中比较有趣的是 LC_TIME ,如果在文字接口下,最好将 LC_TIME 改成美规日期的显示方式,才不会有乱码!
    LC_COLLATE=zh_TW.Big5
    LC_CTYPE=zh_TW.Big5
    LC_MESSAGES=zh_TW.Big5
    LC_MONETARY=zh_TW.Big5
    LC_NUMERIC=zh_TW.Big5
    LC_TIME=en
    LESSOPEN=|/usr/bin/lesspipe.sh %s<==用来设定 less 使用的一支 script 档案
    LOGNAME=test                  <==登入者的账号

    MACHTYPE=i586-mandrake-linux-gnu 
    主机的硬件配备等级 i586 为 P MMX 等级,至于 K7 及 PIII 之后的,就是 i686 等级啰!

    MAIL=/var/spool/mail/test     <==登入者的邮件预设放置地点
    OSTYPE=linux-gnu              <==操作系统的形式(linux-gnu)
    PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/test/bin
    PWD=/home/test                <==目前登入者所在的目录(当下的目录)
    SHELL=/bin/bash               <==登入者使用的 shell 类型
    USER=test                 <==目前这个登入者的使用者名称

    env environment 的简写,所以说,这个指令主要在将目前系统中的主要变量读出来!但是,不是说我们还可以自订变量吗?因此,除了 env 这个读取环境变量的指令之外,还有一个可以将目前系统中所有的变量数据都读出来的指令,称为set !set 除了会将上面的数据都给他读出来之外,还会有额外的这些信息也一起读入(通常都与使用者的设定有关!)
     



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值