学习bash shell 2

  • set
    显示目前系统中全部的变量内容

    语法
    [test @test test]# set
    BASH=/bin/bash                         <==BASH 的主程序放置路径
    BASH_VERSINFO=([0]="2" [1]="05" [2]="8" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") <==BASH 版本信息
    BASH_VERSION=$'2.05.8(1)-release'      <==BASH 的版本
    COLORS=/etc/DIR_COLORS                 <==使用颜色
    COLUMNS=100                         <==目前这个终端机使用的字段有几个字符距离
    HISTFILE=/home/vbird/.bash_history  <==目前用来存过往指令的档案,为一个隐藏档
    HISTFILESIZE=1000                   <==存起来的档案中,指令的最大数(只纪录 1000 个指令)
    IFS=$' \t\n'                        <==预设的分隔符
    langfile=/home/vbird/.i18n             <==语系选择的档案
    LINES=40                               <==目前光标所在的位置为第几行
    MAILCHECK=60                           <==每隔多久检查一次有无新信件(秒数)
    PPID=24572                             <==目前 bash 这个父程序的 ID !
    PROMPT_COMMAND=$'echo -ne "\\033]0;${USER}@${HOSTNAME%%.*}:${PWD/$HOME/~}\\007"'      <==提示字符显示的内容
    SHELLOPTS=braceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs
    SUPPORTED=zh_TW.Big5:zh_TW:zh:en_US:en      <==支援的语系
    TERM=xterm                                  <==终端机形式
    UID=500                                 <==登入者的使用者 ID (UID)
    $                                           <==目前 shell 的 PID 

    最后一个命令的回传值,若之前的命令被正确的执行会传回 0 ,否则会传为 1 或其它错误代码。
    set 的输入就是直接输入 set 即可!他除了会显示出目前的『环境变量』之外,也会显示出您的『自订变量』呢!那么有哪些与使用者较有相关性的自订变量呢?我们上面仅列出部分常见的变量值啰!
     
    使用 set 除了会将系统的默认值秀出来之外,连带的所有的你自己设定的变量也会被秀出来!同时需要注意的是,若当时有相当多人同时在在线的话,那么你的变量只能给自己使用(除非改的是系统的预设参数档,如 /etc/profile ),而不会干扰到别人的!就如同前面所说的,由于你登入 Linux 之后会取得一个 PID ,而你的设定将只对这个 PID 与子程序有关!此外,这次登入所进行的变量设定,如果没有更动到设定档,那么这次设定的变量在下次登入时将被取消掉(因为程序 PID 不见啰!)!所以啰,如果你想要你的变量每次都能在你登入的时候自动就设定好了,那么就必须将你的设定写入登入时加载的设定档
     
    上面的变量中,比较有趣的是 $ 与 ? 这两个咚咚,尤其是 ? 这个变量,如果您上一个命令执行的过程中没有错误,那么这个变量就会被设定为 0 ,如果您的上个命令有错误讯息,那么这个变量会变成 1 或其它的错误代码!现在马上动手试看看您的上个指令执行成果为何?
     
    • echo $?
       

  • 变量设定规则:
    好了,我们知道了一些系统的预设变量了,但是如果是我自己想要设定一些我自己的变量,该如何设定呢?有什么规则需要遵守?呵呵!在说明之前,可能要来让大家了解一下为什么自己会想来设定变量?
    • 我的案例:最简单的例子就是『 路径名称』啰!以鸟哥为例,我的工作在 Unix 系统之下进行一些数值模式的仿真工作,偏偏由于数据量太大,为了怕日后忘记这个目录的内容与主要的意义,所以我的档名都取的很长,偏偏在执行模式的过程中,常常会切换目录!我哩ㄌㄟ,光是打那几行路径名称就快要疯掉了!所以我就设定那几行目录名称成为一个四个字符的变量,如此一来我只要输入『 cd $VARI 』这个指令,嘿嘿!马上就移动到该路径下了!很方便吧!当然变量的意义还不止于此,不过这是最简单的实例说明啰!
    • 我的案例二:另外一个常常需要变量的咚咚是在 scripts 里面,例如我写的一个侦测登录文件的小程序 logfile.sh 这个咚咚,由于里头常常需要用到『储存路径』,偏偏可能每个人的存取路径都不太一样,而如果要修改存取路径的话,嘿嘿!好几十行要同时修改呢!还可能会改错!那么我只要定义一个变量,然后后续的所有数据都使用这个变量的内容!嘿嘿!那么只要大家修改了这个变量的内容(只要一行),后续的动作就不需要修正了!这个动作常在程序或者是 script 当中看到的!
    • 所以啰,有很多的时候为了方便或者是使用于 scripts 的意义,我们必须要设定变量!然而在 bash 底下的变量设定是有一定规则的,必须要来遵守才行:
      1. 变量与变量内容以等号『=』来连结;
      2. 等号两边不能直接接空格符;
      3. 变量名称只能是英文字母与数字,但是数字不能是开头字符;
      4. 若有空格符可以使用双引号『 " 』或单引号『 ' 』来将变量内容结合起来,但须要特别留意,双引号内的特殊字符可以保有变量特性,但是单引号内的特殊字符则仅为一般字符;
      5. 必要时需要以跳脱字符『 \ 』来将特殊符号(如Enter, $, \, 空格符, '等)变成一般符号;
      6. 在一串指令中,还需要藉由其它的指令提供的信息,可以使用 quote 『 ` command` 』;
      7. 若该变量为扩增变量内容时,则需以双引号及 $变量名称如:『 "$PATH":/home』继续累加内容;
      8. 若该变量需要在其它子程序执行,则需要以 export 来使变量可以动作,如『export PATH』;
      9. 通常大写字符为系统预设变量,自行设定变量可以使用小写字符,方便判断(纯粹依照使用者兴趣与嗜好);
      10. 取消变量的方法为:『unset 变量名称』。


      底下我们举几个例子来说明一下:
       

      一般变量设定:
      [tets @test test]# 12name=VBrid           <==错误的!因为变量开头不能是数字!
      [test @test test]# name = VBird                  <==错误的!因为等号两边不能直接接空白!
      [test @test test]# name=VBird                    <==正确的!echo $name 显示 VBird
      [test @test test]# name=VBird name           <==错误的!需要加上双引号!不然会显示错误!
      [test @test test]# name="VBird name"             <==正确的!echo $name 显示 VBird name
      [test @test test]# name="VBird's name"          <==正确的!

      变量累加设定:
      [test @test test]# name=$nameisme         <==错误的!需要以双引号将原变量圈起来
      [test @test test]# name="$name"isme       <==正确的!echo $name 显示 VBird's nameisme
      [test @test test]# PATH="$PATH":/home/test       <==正确的!echo $PATH 将多了后面一句话!
      [test @test test]# PATH="$PATH:/home/test"       <==正确的!这个形式对于 PATH 来说也是正确的格式!

      变量延伸到下一个子程序:
      [test @test test]# name="VBird's name"     <==设定 name 这个变量
      [test @tset test]# echo $name                 <==显示 name 变量的指令
      [test @test test]# VBird's name
      [test @test test]# /bin/bash                  <==另开一个 bash 的子程序
      [test @tset test]# echo $name                 <==显示 name 这个变量
      [test @tset test]#                        <==会显示空字符串因为 name 这个变量不能使用在子程序
      [test @test test]# exit                       <==退出子程序 bash shell !
      [test @test test]# export name                <==正确的!如此则 $name 可以用于下一个子程序中!

      指令中的指令:
      [test @test test]# cd /lib/modules/`uname –r`/kernel
      上式中,会先执行 `uname –r` 这个内含指令,然后输出的结果附加在 /lib/module… 里面,所以执行这个指令,可以完成几个附指令程序!

      取消变量设定:
      [test @test test]# unset name

       
      根据上面的案例你可以试试看!就可以了解变量的设定啰!这个是很重要的呦!请勤加练习!!其中,较为重要的一些特殊符号的使用啰!例如单引号、双引号、跳脱字符、钱字号、quote 符号等等,底下的例题想一想吧!
       
      例题:在变量的设定中,单引号与双引号有什么不同呢?
      答:
      单引号与双引号的最大不同在于双引号仍然可以保有变量的内容,但单引号内仅能是一般字符,而不会有特殊符号。我们以底下的例子做说明:假设您定义了一个变量, name=VBird ,现在想以 name 这个变量定义出 myname 显示 VBird its me 这个内容,要如何订定呢?
      [root @test root]# name=VBird
      [root @test root]# echo $name
      VBird
      [root @test root]# myname="$name its me"
      [root @test root]# echo $myname
      VBird its me
      [root @test root]# myname='$name its me'
      [root @test root]# echo $myname
      $name its me
      发现了吗?没错!使用了单引号的时候,那么 $name 将失去原有的变量内容,仅为一般字符的显示型态而已!这里必需要特别小心在意!
       
      例题:在指令下达的过程中, quote ( ` ) 这个符号代表的意义为何?
      答:
      在一串指令中,在 ` 之内的指令将会被先执行,而其执行出来的结果将做为外部的输入信息!例如 uname –r 会显示出目前的核心版本,而我们的核心版本在 /lib/modules 里面,因此,你可以先执行 uname –r 找出核心版本,然后再以『 cd 目录』到该目录下,当然也可以执行
      cd /lib/modules/`uname –r`
      直接到该目录下去!
       
      底下我们来谈一谈 export 的用途吧!

  • export
    当你取得一个 bash 之后,亦即得到了一个程序了,但是若你再次的执行一次 bash ,那么你将进入『子程序』,这个程序的概念我们在资源管理章节中再详谈,这里您先有个概念即可。那么由于您已经进入了该子程序,所以在父程序中的变量设定将不再继续的存在。如您想要让该变量内容继续的在子程序中使用,那么就请执行:
     
    • export 变数
     
    !这个东西用在『引用他人的档案或者其它程序』时,相当的重要的!尤其像我常常两三个档案互相引用来引用去的,如果忘记设定 export 的话,那么不同的档案中的相同变量值,将需要一再地重复设定才行!所以,我只要在头一个档案使用 export 的话,那么后续的档案引用时,将会把该变量内容读进来!好用的很?而,如果仅下达 export 而没有接变量时,那么此时将会把所有的『环境变量』秀出来喔!也就是说, export 可以将一般自订的变量变成环境变量
     
    [root @test root]# export
    declare -x BASH_ENV="/root/.bashrc"
    declare -x CVSROOT="/usr/local/cvs/src/master"
    declare -x HISTSIZE="50"
    declare -x HOME="/root"
    declare -x HOSTNAME="test.adsldns.org"
    declare -x HOSTTYPE="i386"
    declare -x INPUTRC="/etc/inputrc"
    declare -x LANG="en_US"
    declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s"
    declare -x LOGNAME="root"
    declare -x LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:
    bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=
    01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh
    =01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.z
    ip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;
    31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=
    01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:"
    declare -x MACHTYPE="i386-redhat-linux-gnu"
    declare -x MAIL="/var/spool/mail/root"
    declare -x MANPATH=":/usr/local/netcdf/man"
    declare -x OSTYPE="linux-gnu"
    declare -x PATH="/usr/local/pgi/linux86/bin:/bin:/sbin:/usr/sbin:/usr/bin:
    /usr/local/sbin:/usr/local/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
    :/usr/local/netcdf/bin"
    declare -x PGI="/usr/local/pgi"
    declare -x PWD="/root"
    declare -x SHELL="/bin/bash"
    declare -x SHLVL="1"
    declare -x SSH_TTY="/dev/pts/0"
    declare -x TERM="xterm"
    declare -x USER="root"
     

  • unset
    就是直接将该变量的内容拿掉:
     
    • unset 变数
     

  • 变量的有效范围:
    由前面的 export 以及相关的说明,你可以很清楚的知道一件事情,那就是,『变量的设定只在目前这个 shell 环境当中存在,在下个或者是在子程序中 ( 子 shell ) 将不会存在!』要让变量在下个程序也可以继续的使用,大概就是使用 export 这个咚咚啦!此外,其实除了 shell 的父、子程序外,在脚本( scripts )的编写当中,由于有的软件会使用到 2 个以上的 scripts 做为一个完整的套件!也就是说,假如你有两支程序,一支为 scripts1.sh 以及 scripts2.sh ,而 scripts2.sh 会去引用 scripts1.sh 的变数,这个时候,嘿嘿!你在 scripts1.sh 当中设定的变量请『千万记得以 export 设定』,否则你的变量将无法在两个 scripts 之间互相被引用喔!当这个 scripts 执行完毕之后,刚刚在 scripts 当中设定的变量也就『失效了!』。
     

  • 其它的注意事项:
    乍看之下变量似乎没有什么值得我们来留意的地方,其实不然,变量可以让我们的系统管理变的更加的简单,举个例子来说,刚刚我们提到 HISTSIZE 可以控制历史指令的多寡,那么太多的话,可能会有安全的顾虑之虞,那么是否需要改小一点呢?当然需要~此外,关于路径的设定方面,当您使用一般身份使用者登入系统,再以 su 转换成 root 身份时,基本上,一堆环境变量仍是以当初的一般身份者为主的,因此,您常常会发现 root 使用的指令会『找不到!』那就是环境变量的错误设定啦!这个时候,如果您能够将该一般身份使用者的路径设定成为 root 能用的指令的样子,嗯!那么转换身份的时候,将可以免除相当多的困扰呢!提供给你做为参考了!
     

  • read:
    上面我们谈到的『变量』都是由『指令列』直接设定好的!那么可不可以随时来提供使用只以键盘随时输入变量内容?也就是说,变量内容是由使用者由键盘输入的哩!呵呵!可以使用 read 来达成喔!这个东西在『 script 』里面比较重要啦!所以我们在 shell script 里面会再次的提到喔!
    语法
    [test @test test]# read name
    testing <==这个时候屏幕会等待使用者由键盘输入喔!
    [test @test test]# echo $name
    testing <==刚刚输入的数据变成了变量的内容啦!
     

  • array:
    谈完了一些基本的变量之后,再接下来我们可以聊一聊关于『数组, Array』这东西了!学过数学应该知道有所谓的数组吧!他可以使用一个『函数』来包含一些内容!例如 A(1)=1, A(2)=4, A(3)=8 等等的样子,那个 A(n) 就是函数, n 就是 index(索引),而在等号的右边就是这个函数对应索引所得到的『内容』啦!在 Bash 里头提供了『一维数组』给大家来使用,他的设定格式是:
    语法
    [test @test test]# a[索引]=内容
    [test @test test]# echo ${a[索引]}
    例:
    [test @test test]# a[1]=4
    [test @test test]# a[2]=8
    [test @test test]# echo ${a[1]} ${a[2]}
    4 8
    注意一下喔!在设定数组的时候,他主要是以 『字母及中刮号, abc[]』的样式来设定的!其它的规则则与 变量设定规则 相同!不过,在读取数组的时候就需要比较注意了!读取的时候,是以 ${数组函数} 的方式来读取的!这部份特别容易搞错!请大家特别留意呢!当然啦,数组不止可以进行数字的型态,也可以是字符串的类型喔!都可以的啦!
     

  • $RANDOM:
    有听过『随机取随机数』这个玩意儿吧!?呵呵!那么在 BASH 里面的随机数是那个变数来的?随机数在英文的写法为 RANDOM 啦,所以啰, BASH 当中针对随机数的变量名称就是 $RANDOM 啰!来给他秀一下吧!
    语法
    [test @test test]# echo $RANDOM
    xxxx <==每次都会出现不同的数字喔!
    随机数对于程序设计师比较重要,对于我们一般使用者,重要性就没有这么大啦!只是提出来让大家知道一下就是了!
     

  • eval:
    语法
    [test @test test]# eval variable
    例题:
    [test @test test]# days=365
    [test @test test]# year=days
    [test @test test]# echo \$$year
    $days  <==第一个 $ 被 \ 改变成为一般字符,而 \$ 后面接的 $year 就成为 days 啦!
    [test @test test]# eval echo \$$year
    365
    加上 eval 之后, \$$year 变成的 $days 的『变量内容』会显现出来喔!
    这个指令也是颇有趣的!他主要是用来做为变量的『迭代』用的!以上面的例子来看,起先, \$$year 会变成为 $days ,而这个 $days 其实是一般字符喔!并不是变数!不过,加上了 eval 之后,这个字符串就会被变成变量内容咯!所以说, eval 是用来做为『二次迭代』的功能的!

命令别名与历史命令
  • 命令别名:
    命令别名是一个很有趣的东西,特别是你的惯用指令特别长的时候!还有,增设预设的属性在一些惯用的指令上面,可以预防一些不小心误杀档案的情况发生的时候!举个例子来说,如果你要查询隐藏档,并且需要长的列出与一页一页翻看,那么需要下达『 ls -al | more 』这个指令,我是觉得很烦啦!要输入好几个单字!那可不可以使用 lm 来简化呢?!当然可以,你可以在命令列下面下达:
     
    [test @tset test]# alias lm='ls -al | more'

    要注意的是:『alias 的定义规则与变量定义规则几乎相同』,所以你只要在 alias 后面加上你的{『别名』='指令 参数'},以后你只要输入 lm 就相当于输入了 ls -al|more 这一串指令!很方便吧!另外,我们知道 root 可以移除( rm )任何数据!所以当你以 root 的身份在进行工作时,需要特别小心,但是总有失手的时候,那么 rm 提供了一个参数来让我们确认是否要移除该档案,那就是 -i 这个参数!所以,你可以这样做:
     

    [test @tset test]# alias rm='rm -i'
     
    嘿嘿!那么以后使用 rm 的时候,就不用太担心会有错误删除的情况了!这也是命令别名的优点啰!那么如何知道目前有哪些的命令别名呢?就使用 alias 呀!
     
    [test @tset test]# alias
    alias l.='ls -d .[a-zA-Z]* --color=tty'
    alias ll='ls -l'
    alias lm='ls -al'
    alias ls='ls --color=tty'
    alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

    至于如果要取消命令别名的话,那么就使用 unalias 吧!
     
    那么命令别名与变量有什么不同呢?基本上,他们的意义就不太一样了! alias 这种命令别名,你可以将他想成是建立一个新的指令名称,至于变量则仅是将一个数值或者字符串存在某个代表意义当中!举个例子好了,我们知道以前的 DOS 年代,列出目录与档案就是 dir ,而清除屏幕就是 cls ,那么如果我想要在 linux 里面也使用相同的指令呢?那就以 alias 来进行指令的别名设定:
     

    •   alias cls=’clear’
        alias dir=’ls –l’
     
    只要加入这两行,以后你输入 cls 及 dir 就可以执行了!很方便吧!

  • 历史指令记录数据:
    前面我们提过 bash 有提供指令历史的服务!那么如何查询我们曾经下达过的指令呢?就使用 history 啰!当然,如果觉得 histsory 太麻烦,可以使用命令别名来设定呢!不要跟我说还不会设定呦!
     
    • alias h=’history’
     
    如此则输入 h 等于输入 history 啰!好了,我们来谈一谈 history 的用法吧!

    • history, !command
      显示历史指令记录内容, 下达历史纪录中的指令

      语法
      [test @test test]# history
      [test @test test]# [!number]  [!command] [!!]
      参数说明:
      number   :第几个指令的意思;
      command  :指令的开头几个字母
      !        :上一个指令的意思!
      范例:
      [test @test test]# history          <==底下列出的就是(1)历史指令的编号;(2)指令的内容
         66  man rm
         67  alias
         68  man history
         69  history
      [test @test test]# !66       <==执行第 66 个历史指令
      [test @test test]# !!               <==执行上一个指令(在本例中,就是 !66 那一个指令!)
      [test @test test]# !al              <==执行最近一次以 al 为开头的指令内容,就是第 67 个指令啰!
      说明:
      history 这个指令配合 ! 这个用法就多了!如果我想要执行上一个指令,除了使用上下键之外,我可以直接以 !! 来下达上个指令的内容,此外,我也可以直接选择下达第 n 个指令, !n 来执行,也可以使用指令标头,例如 !vi 来执行最近指令开头是 vi 的指令列!相当的方便而好用!基本上 history 的用途很大的!但是需要小心安全的问题!尤其是 root 的历史纪录档案,这是 Cracker 的最爱!因为不小心的 root 会将很多的重要数据在执行的过程中会被纪录在 ~/.bash_history 当中,如果这个档案被解析的话,后果不堪吶!无论如何,使用 history 配合『 ! 』曾经使用过的指令下达是很有效率的一个指令方法!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值