`
zpball
  • 浏览: 917037 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

unix 下shell编程(一)

阅读更多
*Shell是什么?

  任何发明都具有供用户使用的界面。UNIX供用户使用的界面就是Shell(DOS的command熟悉吧,但UNIX的要强大的多)。 Shell为用户提供了输入命令和参数并可得到命令执行结果的环境。

  为了不同的需要,UNIX提供了不同的Shell。现在的UNIX大部分都支持BourneShell,以下教程就以BourneShell(Bsh)为例,一步步的领略UNIX Shell的强大功能,占先其强大魅力,达到更方便灵活的管理、应用UNIX的目的。

  1.UNIX内核和Shell的交互方法

  启动UNIX时,程序UNIX(内核)将被调入计算机内存,并一直保留在内存中直到机器关闭。在引导过程中,程序 init将进入后台运行一直到机器关闭。该程序查询文件/etc/inittab,该文件列出了连接终端的各个端口及其特征。当发现一个活动的终端时,init程序调用getty程序在终端上显示login等登陆信息。(username和passwd),在输入密码后, getty调用login进程,该进程根据文件/etc/passwd的内容来验证用户的身份。若用户通过身份验证,login进程 把用户的home目录设置成当前目录并把控制交给一系列setup程序。setup程序可以是指定的应用程序,通常setup程序 为一个Shell程序,如:/bin/sh 即Bourne Shell(command出来了,呵呵)。

  得到控制后,Shell程序读取并执行文件/etc/.profile以及.profile。这两个文件分别建立了系统范围内的和 该用户自己的工作环境。最后Shell显示命令提示符,如$。(这是以bsh为例,若是csh,为.cshrc,ksh为.kshrc,bash为.bashrc等等)    

  注:(不妨把/etc/.profile和.profile看成DOS的autoexec.bat 或 config.sys文件)

  当shell退出时,内核把控制交给init程序,该程序重新启动自动登陆过程。有两种方法使shell退出,一是用户执行exit命令,二是 内核(例如root用kill命令)发出一个kill命令结束shell进程。shell退出后,内核回收用户及程序使用的资源。

  用户登陆后,用户命令同计算机交互的关系为:命令进程--->Shell程序--->UNIX内核--->计算机硬件。当用户输入一个命令,如$ls, Shell将定位其可执行文件/bin/ls并把其传递给内核执行。内核产生一个新的子进程调用并执行/bin/ls。当程序执行完毕后,内核取消 该子进程并把控制交给其父进程,即Shell程序。例如执行:

    $ps

    该命令将会列出用户正在执行的进程,即Shell程序(下来详细说说,别急现在)和ps程序。若执行:

    $sleep 10 &
    $ps

  其中第一条命令将产生一个在后台执行的sleep子进程。ps命令执行时会显示出该子进程。

  每当用户执行一条命令时,就会产生一个子进程。该子进程的执行与其父进程或Shell完全无关,这样可以使Shell去做其他工作。(Shell只是把用户的意图告诉内核,然后该干嘛干嘛:)) 现在windows有个计划任务(在固定的时间,日期自动执行某任务),其实UNIX很早就有这个功能了,也就是所谓的Shell的自动执行。一些UNIX 资源,如cron可以自动执行Shell程序而无需用户的参与,(这个功能好象在/var/spool/crotab目录里)。

Crontab 程序对于系统管理员来说是非常有用的。Cron 服务用于计划程序在特定时间(月、日、周、时、分)运行。我们以root的crontab 为例。根用户的 crontab 文件放在 /var/spool/crontab/root 中,其格式如下:

  (1)  (2)  (3)  (4)  (5)  (6)
   0   0   *   *   3   /usr/bin/updatedb
      1. 分钟 (0-60)
      2. 小时 (0-23)
      3. 日 (1-31)
      4. 月 (1-12)
      5. 星期 (1-7)
      6. 所要运行的程序
  2.Shell的功能和特点
  1>命令行解释
  2>使用保留字
  3>使用Shell元字符(通配符)
  4>可处理程序命令
  5>使用输入输出重定向和管道
  6>维护一些变量
  7>运行环境控制
  8>支持Shell编程

  对于"命令行解释"就不多说了,就是在shell提示符(例如:"$","%","#"等)后输入一行unix命令,Shell将接收用户的输入。

  "使用保留字":Shell有一些具有特殊意义的字,例如在Shell脚本中,do,done,for等字用来控制循环操作,if,then等控制条件操作。 保留字随Shell环境的不同而不同。

  "通配符":* 匹配任何位置
       ? 匹配单个字符
       [] 匹配的字符范围或列表 例如:
       
          $ls [a-c]*
         
          将列出以a-c范围内字符开头的所有文件
          $ls [a,m,t]*
         将列出以e,m或t开头的所有文件

  "程序命令" :当用户输入命令后,Shell读取环境变量$path(一般在用户自己的.profile中设置),该变量包含了命令可执行文件可能存在的目录列表。 shell从这些目录中寻找命令所对应的可执行文件,然后将该文件送给内核执行。

  "输入输出重定向及管道" :重定向的功能同DOS的重定向功能:

     ">" 重定向输出
     "<" 重定向输入

  而管道符号,是unix功能强大的一个地方,符号是一条竖线:"|",用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2,例如:

    $ls -s|sort -nr|pg

  该命令列出当前目录中的所有文件,并把输出送给sort命令作为输入,sort命令按数字递减的顺序把ls的输出排序。然后把排序后的 内容传送给pg命令,pg命令在显示器上显示sort命令排序后的内容。

  "维护变量" :Shell可以维护一些变量。变量中存放一些数据供以后使用。用户可以用"="给变量赋值,如:

         $lookup=/usr/mydir

该命令建立一个名为lookup的变量并给其赋值/usr/mydir,以后用户可以在命令行中使用lookup来代替/usr/mydir,例如:          
         $echo $lookup
         结果显示:/usr/mydir

         为了使变量能被子进程使用,可用exprot命令,例如:

         $lookup=/usr/mydir
         $export lookup

  "运行环境控制" :当用户登陆启动shell后,shell要为用户创建一个工作的环境,如下:

  1>当login程序激活用户shell后,将为用户建立环境变量。从/etc/profile和.profile文件中读出,在这些文件中一般都用$TERM 变量设置终端类型,用$PATH变量设置Shell寻找可执行文件的路径。

  2>从/etc/passwd文件或命令行启动shell时,用户可以给shell程序指定一些参数,例如"-x",可以在命令执行前显示该命令及其参数。后面详细介绍这些参数。

  "shell编程" :本文主要介绍的内容。

  shell本身也是一种语言(*可以先理解为unix命令的组合,加上类C的条件,循环等程序控制语句,类似dos批处理,但要强大的多),用户可以 通过shell编程(脚本,文本文件),完成特定的工作。

SHELL变量

  下面我们详细的介绍Bourne Shell的编程:

  自从贝尔实验室设计了Bourne Shell。从那时起许多厂商根据不同的硬件平台设计了许多版本得unix。但在众多版本的unix中,Bourne Shell 一直保持一致。
  1>Bsh的启动:用户在登陆后,系统根据文件/etc/passwd中有关该用户的信息项启动Shell。例如某用户在passwd中 的信息项为:

    ice_walk:!:411:103:Imsnow ,ice_walk:/home/ice_walk:/bin/bsh

  则表明,用户名是ice_walk等信息,在最后一项"/bin/bsh"表明用户的sh环境类型是bsh,于是系统启动之。在启动或执行(包括下面我们要讲 的shell程序--脚本)过程中可以使用以下一些参数,我们一一说明:

  -a 将所有变量输出
  -c "string"从string中读取命令
  -e 使用非交互式模式
  -f 禁止shell文件名产生
  -h 定义
  -i 交互式模式
  -k 为命令的执行设置选项
  -n 读取命令但不执行
  -r 受限模式
  -s 命令从标准输入读取
  -t 执行一命令,然后退出shell
  -u 在替换时,使用未设置的变量将会出错
  -v 显示shell的输入行
  -x 跟踪模式,显示执行的命令

许多模式可以组合起来用,您可以试试了,但-ei好象不行,你说why呢?

  使用set可以设置或取消shell的选项来改变shell环境。打开选项用"-",关闭选项用"+",多数unix允许打开或关闭a、f、e、h、k、n、 u、v和x选项。若显示Shell中已经设置的选项,执行:

    $echo $-

  Bsh中每个用户的home目录下都有一个.profile文件,可以修改该文件来修改shell环境。为了增加一个可执行文件的路径(例如/ice_walk/bin), 可以把下面代码加入.profile中

    PATH=$PATH:/ice_walk/bin;exprot PATH

   .profile中shell的环境变量意思如下:

    CDPATH 执行cd命令时使用的搜索路径
    HOME 用户的home目录
    IFS 内部的域分割符,一般为空格符、制表符、或换行符
    MAIL 指定特定文件(信箱)的路径,有UNIX邮件系统使用
    PATH 寻找命令的搜索路径(同dos的config.sys的 path)
    PS1 主命令提示符,默认是"$"
    PS2 从命令提示符,默认是">"
    TERM 使用终端类型

  2>Bsh里特殊字符及其含义

  在Bsh中有一组非字母字符。这些字符的用途分为四类:作为特殊变量名、产生文件名、数据或程序控制以及引用和逃逸字符控制。他们 可以让用户在Shell中使用最少的代码完成复杂的任务。

     *> Shell变量名使用的特殊字符
        $# 传送给命令Shell的参数序号
        $- 在Shell启动或使用set命令时提供选项
        $? 上一条命令执行后返回的值
        $$ 当前shell的进程号
        $! 上一个子进程的进程号
        $@ 所有的参数,每个都用双括号括起
        $* 所有参数,用双括号括起
        $n 位置参数值,n表示位置
        $0 当前shell名
     *>产生文件名的特殊字符
        包括"*","?","[]",上面讲过,不再多说。
     *>数据或程序控制使用的特殊字符
        >(file) 输出重定向到文件中(没有文件则创建,有则覆盖)
        >>(file) 输出重定向到文件中(没有则创建,有则追加到文件尾部)
        <(file) 输入重定向到文件
        ; 命令分割符
        | 管道符
        & 后台运行(例如:sleep 10 &)
        ` ` 命令替换,重定向一条命令的输出作为另一命令的参数
     *>对于引用或逃逸的特殊字符

Bsh用单引号' '和双引号" "将特殊字符或由空白分隔的字引用起来组成一个简单的数据串.使用单引号和双引号的区别是双引号中的内容可进行参数和变量替换.逃逸字符也一样.

        $echo "$HOME $PATH"
         结果显示$/u/ice_walk/bin:/etc:/usr/bin
        而$echo '$HOME $PATH' 结果显示$HOME $PATH

  shell的逃逸符是一个"\",表示其后的字符不具有特殊的含义或不是shell的函数

        $echo \$HOME $PATH
        结果显$$HOME /bin:/etc:/usr/bin:

3>Bsh的变量

  前面我们在多个地方引用了变量,当Shell遇到一个"$"符时(没有被引用或逃逸),它将认为其后为一变量。不论该变量是环境变量还是用户自定义的变量,在命令行中变量名要被变量值替换。例如命令:ls $HOME将列出变量HOME对应目录下的文件。 用户可以在命令行中的任何地方进行变量替换。包括命令名本身,例如:

    $dir=ls
    $$dir f*

  将列出以f开头的文件。

  现在详细的介绍下Bsh的变量。Bsh中有四类变量:用户定义的变量、位置变量(shell参数)、预定义变量及环境变量。

  用户定义的变量:

  用户定义的变量由字母和下划线组成,并且变量名的第一个字符不能为数字(0~9)。与其他UNIX名字一样,变量名是大小写敏感的。用户可以在命令行上用"="给变量赋值,例如:

    $NAME=ice_walk

  给变量NAME赋值为ice_walk,在应用变量NAME的时候,在NAME前加"$"即可,前面已说,不再废话(别说我废话多,关键是没当过老师:()。可以用变量和其他字符组成新的字,例如:

    $SUN=sun
    $echo ${SUN}day

  在应用shell变量时候,可以在变量名字两边$后面加上{},以更加清楚的显示给shell,哪个是真正的变量,以实现字符串的合并等功能。
 
  结果显示:sunday(注意不能echo $SUNday,因为SUNday变量没定义,读者试下执行结果) 用户也可以在命令行上同时对多个变量赋值,赋值语句之间用空格分开:

    $X=x Y=y

    注意变量赋值是从右到左进行的

    $X=$Y Y=y
    X的值是y
    $X=z Y=$Z

    Y的值是空(变量未赋值时,shell不报错,而是赋值为空)

  用户可以使用"unset <变量>"命令清除给变量赋的值

用户使用变量时要在其前面加一"$"符,使变量名被变量值所替换。Bsh可以进行变量的条件替换,即只有某种条件发生时才进行替换。替换条件放在一对大括号{}中,如:

    ${variable: -value} variable是一变量值,value是变量替换使用的默认值

    $echo Hello $UNAME
    结果显示:Hello
    $echo Hello ${UNAME: -there}
    结果显示:Hello there
    $echo $UNAME
    结果显示: (空)
    $UNAME=John
    $echo Hello ${UNAME: -there}
    结果显示:Hello John

  可以看出,变量替换时将使用命令行中定义的默认值,但变量的值并没有因此而改变。另外一种替换的方法是不但使用默认值进行替换,而且将默认值赋给该变量。其形式如下:

    ${variable:=value}

  该形式在变量替换后同时把值value符给变量variable。

    $echo Hello $UNAME
    结果显示:Hello
    $echo Hello ${UNAME:=there}
    结果显示:Hello there
    $echo $UNAME
    结果显示:there
    $UNAME=John
    $echo Hello ${UNAME:-there}
    结果显示:Hello John

  变量替换的值也可以是` `括起来的命令:

    $USERDIR={$Mydir: -`pwd`}

  第三种变量的替换方法是只有当变量已赋值时才用指定值替换形式:

    ${variable: +value}

    只有变量variable已赋值时,其值才用value替换,否则不进行任何替换,例如:

    $ERROPT=A
    $echo ${ERROPT: +"Error tracking is acitive"}
    结果显示:Error tracking is acitive
    $ERROPT=
    $echo ${ERROPT: +"Error tracking is acitive"}
    结果显示: (空)

  我们还可以使用错误检查的条件进行变量替换:

    ${variable:?message}

当变量variable已设置时,正常替换。否则消息message将送到标准错误输出(若此替换出现在shell程序中,那么该程序将终止)。 例如:

    $UNAME=
    $echo $ {UNAME:?"UNAME HAS NOT BEEN SET"}
    结果显示:UNAME HAS NOT BEEN SET

    $UNAME=Stephanie
    $echo $ {UNAME:?"UNAME HAS NOT BEEN SET"}

    结果显示:Stephanie
    当没有指定message时,shell将显示一条默认的消息,例如:

    $UNAME=
    $echo $ {UNAME:?}
    结果显示:sh:UNAME:parameter null or not set

4>位置变量或Shell参数

  在shell解释用户的命令时,将把命令行的第一个字作为命令,而其他的字作为参数。当命令对应的可执行文件为Shell程序时,这些参数将作为位置变量传送给该程序。第一个参数记为$1,第二个为$2....第九个为$9。其中1到9是真正的参数名,"$"符只是用来标识变量的替换。

  位置变量$0指命令对应的可执行文件名。在后面将详细介绍位置变量。

  1.只读变量

  用户将变量赋值后,为了防止以后对该变量的修改,可以用以下命令将该变量设置为只读变量:

    readonly variable

  2.export命令

  shell执行一个程序时,首先为该程序建立一个新的执行环境,称为子shell。在Bourne Shell中变量都是局部的,即他们只在创建他们的Shell中有意义。用户可以用export命令让变量被其他子Shell识别。但某用户的变量是没法让其他用户使用的。

  当用户启动一个新shell时,该shell将使用默认的提示符。因为赋给变量PS1的值只在当前shell中有效。为了让子Shell使用当前Shell中定义的提示符号,可以使用export命令:

    $PS1="Enter command:"
    Enter command:export PS1
    Enter command:sh
    Enter command:

    此时变量PS1变成了全局变量。它可以被其子Shell使用。当变量被设置成全局的以后,将一直保持有效直到用户退出该变量所在的Shell。用户可以在文件.profile中给一个变量永久赋值。详见"规范Shell"。

基本语句

  从本节起,我们将详细介绍Shell程序设计的基本知识,通过编写Shell脚本,用户可以根据自己的需要有条件的或者重复的执行命令。通过Shell程序,可以把单个的UNIX命令组合成一个完全实用的工具,完成用户的任务。

  1>什么是Shell程序

  当用户在UNIX Shell中输入了一条复杂的命令,如:

    $ls -R /|greo myname |pg

  我们可以称用户在对Shell编程,当把这条语句写在一个文件里,并且符给该文件可执行权限,那么该文件就是我们传统上说的Shell程序。

  2>简单的Shell程序

  假设用户每天使用下述命令备份自己的数据文件:

    $cd /usr/icewalk;ls * |cpio -o > /dev/fd0

  我们可以把它写在一个文件,如:ba.sh中:

    $cat >ba.sh
    cd /usr/icewalk
    ls * |cpio -o > /dev/fd0
    ^D  (ctrl_d)

  程序ba.sh就是Shell脚本,用户可以用vi或其他编辑工具编写更复杂的脚本。

  此时用户备份文件只需要执行Shell程序ba.sh,执行时需在当前Shell中创建一个子Shell:

    $sh ba.sh

  程序sh与用户登陆时执行的Bourne Shell相同,但当Sh命令带参数ba.sh后,它将不再是一个交互式的Shell,而是直接从文件ba.sh中读取命令。

  执行ba.sh中命令的另一方法是给文件ba.sh执行权限:

    $chmod +x ba.sh

  此时,用户可以输入文件名ba.sh做为一个命令来备份自己的数据,需要注意的是,用这种方法执行命令的时候,文件ba.sh必须存在于环境变量$PATH所指定的路径上。
分享到:
评论

相关推荐

    Linux与UNIX Shell编程指南.pdf

    Linux与UNIX Shell编程指南是计算机科学领域中一本经典的指南手册,旨在帮助读者快速掌握Linux与UNIX操作系统下的shell编程技术。下面是从该书中生成的相关知识点: 1. Shell概述 Shell是Linux与UNIX操作系统下的...

    shell编程入门教程+shell脚本专家指南+UNIX.shell编程24小时教程.rar

    Shell编程是Linux/Unix操作系统中的一种重要工具,它允许用户通过命令行与系统进行交互,执行各种任务。本文将深入探讨Shell编程的基础知识,包括基本语法、常用的内置命令、条件语句、循环结构以及函数的使用,旨在...

    Unix Shell Shell编程

    6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书

    UNIX.Shell编程24学时教程.pdf

    UNIX操作系统自诞生以来,一直在高端应用...总体而言,《UNIX.Shell编程24学时教程》是一本结构合理、内容丰富的学习资料,适合UNIX开发人员及计算机应用人员阅读,通过系统学习,读者可以提高UNIX Shell编程的能力。

    LINUX与UNIX SHELL编程指南.rar

    LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 ...

    linux与unix_shell编程指南

    《Linux与Unix Shell编程指南》是一本专注于操作系统交互和脚本编写的重要教程。在Linux和Unix系统中,Shell是用户与操作系统内核交互的主要界面,它提供了命令行接口,允许用户执行各种操作,如文件管理、系统管理...

    shell编程入门经典--LINUX与UNIX Shell编程指南 (中文pdf版)

    《LINUX与UNIX Shell编程指南》是一本专为初学者设计的shell编程教程,它深入浅出地介绍了在Linux和UNIX系统中如何使用Shell进行高效自动化任务处理。Shell编程是Linux和UNIX系统中的核心技术,它允许用户通过命令行...

    UNIX命令及SHELL编程

    这是一套完整的Unix培训教材,包括Unix常用命令及SHELL编程基础与高级技巧,PDF格式,共30个文件。另有2个Word文档。包内文件清单如下: 01_Shell-文件安全与权限.PDF 02_Shell-使用find和xargs.PDF 03_Shell-...

    UNIX shell语言编程24小时学会

    UNIX操作系统自诞生...总的来说,本书《UNIX shell语言编程24小时学会》是一本针对UNIX Shell编程初学者的实用入门指南,通过系统的讲解和实践练习,能够让读者在短时间内快速入门并掌握Shell编程的核心知识和技能。

    UNIX_SHELL编程课程讲义

    UNIX_SHELL编程课程讲义 包括UNIX虚拟机的安装使用、CRT使用、UItraEdit工具使用、shell的概述、shell变量、shell控制结构、shell函数、shell script编程实例

    unix shell编程第三版笔记

    在IT领域,Unix Shell编程是一种极其重要的技能,尤其对于系统管理员和开发者来说。"Unix Shell编程第三版笔记"是铁道出版社出版的一本教材,它深入浅出地讲解了Unix Shell编程的基础和高级技巧。这份笔记涵盖了从...

    Unix.Shell编程(第三版).zip

    《Unix Shell编程(第三版)》是一本深入探讨Unix Shell编程技术的专业书籍,适用于那些希望在Unix或类Unix操作系统环境中提升自动化任务处理能力的读者。Shell编程是Unix系统中的核心功能之一,它允许用户通过编写...

    绝版经典 LINUX与UNIX SHELL编程指南 PDF 高清版 [16.3M]

    本书共分五部分 ,详细介绍了SHELL编程技巧,各种UNIX命令及语法,还涉及了UNIX的文字处理以及少量的系统管理问题。本书内容全面,文字简洁流畅,适合SHELL编程人员学习、参考。 目录 第一部分 SHELL 第一章 文件...

    unix linux shell编程

    这十八个PDF文件详细介绍了Shell编程的各种命令和技巧,对于深入理解和掌握Unix/Linux环境下的自动化工作流程至关重要。 1. **基础概念**: - **Shell类型**:Unix和Linux中有多种Shell,如Bash(Bourne-Again ...

    Unix Shell编程工具

    Unix Shell编程工具是Unix/Linux操作系统中的重要组成部分,它既是用户与操作系统交互的界面,也是一种强大的编程语言。在本文中,我们将深入探讨Unix Shell的核心概念、常用工具以及它们在实际问题解决中的应用。 ...

    UNIX.shell编程24学时教程

    这是一本专为初学者设计的深入浅出的UNIX Shell编程教程,旨在帮助读者在短短24学时内迅速掌握这一强大的脚本语言。Shell编程是UNIX系统中不可或缺的一部分,它允许用户通过命令行界面自动化执行任务,提高工作效率...

Global site tag (gtag.js) - Google Analytics