Linux操作系统实用教程教学课件第六章

上传人:痛*** 文档编号:151259006 上传时间:2022-09-12 格式:PPT 页数:81 大小:908KB
返回 下载 相关 举报
Linux操作系统实用教程教学课件第六章_第1页
第1页 / 共81页
Linux操作系统实用教程教学课件第六章_第2页
第2页 / 共81页
Linux操作系统实用教程教学课件第六章_第3页
第3页 / 共81页
点击查看更多>>
资源描述
Linux操作系统实用教程第6章 Red Hat Linux 9的shell程序 6.1 shell简介 6.2 创建和执行shell程序 6.3 shell环境变量及设置文件 6.4 shell脚本编程 6.5 shell程序跟踪第6章 Red Hat Linux 9的shell程序本章概述本章概述Shell的原意是外壳,用来形容物体外部架构。各种操作系统都有自己的shell,在DOS系统中,它的shell就是程序,而Windows操作系统的程序shell是explorer.exe程序。与Windows等操作系统不同,Linux系统中将shell独立于操作系统核心程序之外,使得用户可以在不影响操作系统本身的情况下进行修改,更新版本或添加新的功能。6.1 shell的简介 6.1.1 shell及shell编编程操作系统的shell程序,介于用户和操作系统内核(Kernel)之间,负责将用户的命令解释成操作系统可以接受的指令,然后由操作系统来执行这些指令,并将操作系统执行的结果以用户可以了解的方式反馈给用户。6.1.1 shell及shell编编程在Linux系统中,shell是操作系统的外壳,为用户提供使用操作系统的接口,它是命令语言、命令解释程序和程序设计语言的统称。shell是用户和操作系统之间的一个接口。用户在命令提示符下输入的每个命令都首先由shell程序进行解释,然后再传给Linux内核的。6.1 shell的简介 6.1.1 shell及shell编编程shell是一个命令解释器。它拥有自己内建的shell命令集,可以用它来启动、挂起、停止一些程序。此外shell也能被系统中的其他有效的Linux应用程序所调用。shell还是一个解释型的程序设计语言。shell程序设计语言支持绝大多数高级程序设计语言中常用的元素,比如函数、变量、数组和控制结构。shell编程简单易学,在任何命令提示符中能键入的命令都可以在shell程序中使用。而且一旦掌握,它将成为工作中的得力工具。和DOS和Windows不同,Linux提供了多种shell程序供用户选择使用,使用不同类型shell的原因是它们都有各自的特点。一般某个用户登录系统时的shell都在/etc/passwd6.1 shell的简介 6.1.1 shell及shell编编程文件的最后一个字段中定义,用户可以通过修改该字段来替换其使用的shell。另外,用户在文本模式下登录系统后,Linux的初始化程序initd就会为每个用户启动一个shell,可以使用“Alt+F1F6”来获取shell提供的多个虚拟控制台,使用虚拟控制台的最大好处就是,当一个虚拟控制台上的程序由于出错给锁住输入时,用户可以进入另一个虚拟控制台,然后杀死该进程。如果系统使用了X Window的图形模式,那么虚拟终端的切换就要使用“Ctrl+Alt+F1F6”。6.1 shell的简介 6.1.2 bash6.1.2 bash在Linux中,用户可以选择使用多种不同类型的shell。在RedHat Linux 9的/etc/shells文件中,列出了目前系统可以使用的shell。并且给出了这些shell程序的位置。具体如下图所示。RedHat Linux 9中的shell6.1 shell的简介 6.1.2 bash最常用的几种shell是Bourne shell(sh)、C shell(csh)、Ash shell(ash)、Korn shell(ksh)和Bourne Again shell(bash)等。每种shell都有自己的特点,一般的Linux系统默认使用bash。1bash简简介Bourne shell是最早被大量使用及标准化的shell,几乎所有的Linux都支持它。它是由贝尔实验室开发的,由于开发者是Steven Bourne,所以被命名为“Bourne shell”。Bourne Again shell(bash)是Bourne shell的扩展,与Bourne shell完全兼容,并且在其基础上增加和增强了很多功能。其中包括了很多csh和ksh的优点。bash不仅有非常灵活和强大的编程接口,同时又有非常友好的用户界面。它内建40个shell命令和12个命令行参数。目前bash6.1 shell的简介 6.1.2 bash是大多数Linux默认的shell,RedHat Linux 9也默认使用bash。bash有许多特色,可以使用方向键查阅以前输入的命令,即history功能。可以对命令行进行编辑,甚至可以在忘记了命令名时请求shell通过命令行补齐进行帮助,方法就是在敲入命令的一部分时,再按下Tab键即可。例如,在命令行提示符下输入ls,再按下“Tab”键,bash会帮助用户列出所有以“ls”打头的命令名,供用户选择。如图下所示。bash的命令行补齐6.1 shell的简介 6.1.2 bashbash也内建了帮助功能,可以给出所有内建命令和每个系统命令的帮助信息。可以使用“help”的方法获得指定命令的帮助信息。在RedHat Linux 9中环境表变量SHELL记录了系统当前使用的shell程序的名称,可以通过返回环境变量SHELL的值来查看当前系统使用的shell程序,如图下所示。查看系统当前的shell6.1 shell的简介 6.1.2 bash2bash的功能shell是操作系统的外壳。RedHat Linux 9中默认使用的shell是bash,它为用户提供使用操作系统的接口,承担着用户与操作系统内核之间进行沟通的任务。除此之外,bash程序还兼备如下的功能:1)交互式处理从用户登录系统开始,shell程序就是在系统终端中显示不同的命令行提示符(root用户登录系统则提示符显示“#”,普通用户登录则显示“$”),然后等待用户输入命令。在接收来自用户输入的命令后,bash会根据命令的不同的类型(包括程序或shell内置命令)来执行,在执行完毕后,bash将结果回传给用户,并且再次回到命令提示符,以等待用户的下一次输入。这种模式会一直继续下去,直6.1 shell的简介 6.1.2 bash到用户执行exit或是按下Ctrl+D来注销,bash才会结束,bash的这种与用户沟通的方式称为“交互式处理”。2)命令补全功能所谓“命令补全”是指在用户输入命令的时候,无需输入完整的命令行,Linux系统的shell会自动查找出最符合的命令名称,供用户选择。这样的功能可以帮用户节省输入长串命令的时间。例如,在/root目录下有一个testexecvp.c文件,如果想查看其中的内容,并不需要完整输入该文件的名称,而只要输入开头的几个字母,即输入“more/root/teste”,然后按下Tab键一次,Linux的bash会自动补足完整的命令(more/root/testexecvp.c)。6.1 shell的简介 6.1.2 bash另一种情况就是,如果系统中有多个文件都与输入的前缀相同,那么当用户连续按下2次Tab键时,系统会显示当前目录下所有具有相同前缀的文件名称,供用户选择。例如,输入“more test”后按2次Tab键,结果如图下所示。bash的补齐功能6.1 shell的简介 6.1.2 bashshell的补全功能,不但方便,而且可以避免由于用户输入错误的路径而执行错误的程序。3)查阅历史记录history命令在RedHat Linux 9中,每当用户输入的命令并按下Enter后,都会被记录在命令记录表中,默认情况下,bash默认使用的命令记录表文件为用户主目录下的.bash_history(文件名前面的“.”表示这是一个隐藏文件)文件。可以使用环境变量HISTSIZE来定义命令记录表的条数,默认的记录条数为1000条。6.1 shell的简介 6.1.2 bash在RedHat Linux 9中可以直接浏览.bash_history文件,或使用history命令来查看目前的命令记录。如下图所示。bash的补齐功能6.1 shell的简介 6.1.2 bash系统提供的history命令可以列出完整的系统在该用户登录时执行过的所有命令,并以命令执行的先后顺序列出记录的号码。如果要查看最近执行的命令,则可以使用“history n”命令,其中,n表示需要查看的最近执行的命令的条数。如下图所示,列出系统最近执行的10条命令。查看最近的10条命令记录6.1 shell的简介 6.1.2 bashbash的history功能提供了一种执行命令的最快的方法,就是使用命令记录号码。在RedHat Linux 9的命令记录中,每条用户执行过的命令都会被赋一个记录号码,用户可以利用这些记录号码来执行指定的要执行的旧命令。其语法如下:!例如,要执行478条记录标记的命令,可以在命令行提示符下执行如下:rootmyhost root#!478结果如右图所示。使用!执行命令6.1 shell的简介 6.1.2 bash4)别名(alias)功能Linux中的别名功能是指提供给用户使用自定义的简单字符串,来替换复杂的命令选项,或是替换连续多个命令的连续组合的功能,从而使得用户可以自定义符合自己习惯的操作命令。例如,对于熟悉DOS和Windows的用户来说,dir命令可以方便地显示当前目录的内容,但是在Linux中完成该功能的命令是“ls l”。如果希望使用dir来代替ls l,则可以使用alias功能来创建一个到ls l的别名,如下图所示。bash的alias功能6.1 shell的简介 6.1.2 bash如果希望查看当前Linux系统中使用的别名命令,可以直接输入“alias”命令。如果需要取消特定的别名命令,可以使用unalias命令。例如,取消dir别名命令可使用如下命令。rootmyhost root#unalias dir使用alias命令查看并取消别名命令的结果如下图所示。查看并取消别名命令6.1 shell的简介 6.1.2 bash5)后台处理Linux是多用户多任务的操作系统,它允许多个用户同时登录系统,也允许多个程序同时执行。但因为shell使用交互式模式,目前执行的命令会一直掌握系统的控制权,直到该程序结束为止,这类程序称为前台程序(Foreground)。shell采用的这种前台程序接管系统控制权的模式,使得个别用户无法使用Linux提供的多任务功能来增加效率,因此,shell提供了后台处理功能来解决上述问题。6.1 shell的简介 6.1.2 bash通常,Linux后台运行的都是比较耗时的程序,如编译核心或是下载Linux的安装文件等,但是后台任务在执行期间,用户仍然可以和shell继续交互,以下达其他的命令。要在RedHat Linux 9中要执行后台程序,只要在输入命令的时候,在命令后面加上“&”符号。系统就会开始以后台的方式执行该命令,屏幕将显示该后台运行程序的进程PID,然后shell将回到命令提示符状态,以等待用户的下一个命令的输入。例如,将top命令投入后台运行。如下图所示。后台运行top6.1 shell的简介 6.1.2 bash当前某个任务在前台运行之后,就无法使用“&”将它投入后台运行,但是可以先使用“Ctrl+z”组合键暂停该程序,然后在命令提示符下输入“bg”命令,即可将该任务投入后台执行。如果要查看目前系统中正在运行的后台程序,可以使用jobs命令。6)输入/输出重定向在Linux系统中,标准输入和输出有3种形态:标准输入(stdin):通常是指键盘。标准输出(stdout):通常是指将命令执行的结果输出到终端机或屏幕上。标准错误输出(stderr):是指在命令发生错误时,将其错误信息输出到屏幕上。6.1 shell的简介 6.1.2 bash一般情况下,程序的输入对象都是标准输入,输出是标准输出。在Linux中提供了输入(和和)的重新定向功能,它可以将程序的输入和输出由标准设备重定向到文件、打印机或其他装置(/dev/null)。这里重定向(和和)是追加重定向,就是新的内容将被添加到文件原来内容的后面。例如,先使用ls命令查看/etc/pam目录的内容,然后将查看结果重定向到ls_result.txt文件中。其命令和执行结果如图所示。6.1 shell的简介 6.1.2 bash然后使用输入重定向查看ls_result.txt文件,可在命令提示符中输入如下命令:rootmyhost root#cat、|和!,还有以下可以在shell中使用的特殊字符。1)通配符(*和?)“*”和“?”是Linux系统中最常用的两个通配符,在字符串查找的时候,通配符可以代替任意的字符。其中“?”可以代替一个任意字符,“*”可以代替任意多个字符。例如,执行“ls l/root/test*”命令就会列出/root目录下所有以test打头的所有文件名,如下图所示。6.1 shell的简介 6.1.2 bash2)命令取代符()命令取代符“”在Esc键下方,与“”符号在同一个键上。两个“”符号包围的命令,是该命令行中首先被执行的命令。例如,“echo date”命令,首先执行date命令,然后使用echo来显示date命令的结果,而不是显示字符串date,如下图所示。命令取代符“”的使用6.1 shell的简介 6.1.2 bash3)命令分隔符(;)如果需要执行一连串的命令,可以一次输入这些命令,而在命令间使用“;”分隔,Linux的shell会一次解释并执行这些命令。例如,在Linux的终端中,从/root目录下先执行cd/etc命令,然后再执行more passwd命令来查看/etc/passwd文件的内容,其过程如下图所示。rootmyhost root#cd/etc;more passwd命令分隔符“;”的使用6.1 shell的简介 6.1.2 bash4)注释符(#)注释符“#”通常使用在Linux的shell脚本程序或应用程序的配置文件中,使用“#”开头的行为注释行,shell在解释该脚本程序的时候不会执行该行。对于有经验的程序员来说,注释行的使用可以增加程序的可读性,也可以使日后的维护更加简单。6.2创建和执行shell程序随着Linux图形界面的日益完善,依靠GNOME或KDE提供的图形界面已经能够完成大部分基本的应用。但是图形界面的功能是有限的,只能完成一些可以预见的功能。例如,如果需要大批量地创建系统用户,使用图形界面是非常耗时的。此时就可以选择使用shell脚本程序。Linux的shell程序是一个非常有用且很容易掌握的工具,可以帮助用户轻松地完成繁重的任务,提高使用和维护系统的效率。另外,Linux的图形界面也是通过shell脚本解释启动的,很多应用程序本身就是一个shell程序。6.2创建和执行shell程序shell程序与C语言等高级语言程序不同,shell程序是通过shell命令解释器解释执行的,不生成二进制的可执行代码,这一点和DOS下的批处理文件类似。不同的shell解释器对应的shell程序的语法也不完全相同。由于bash是Linux下默认提供的shell解释器,并且bash也是使用最广泛、与其他shell兼容性最好的解释器,因此下面介绍的shell程序的知识都是基于bash解释器的。创建和执行一个shell程序非常简单,一般需要以下3个步骤:(1)利用文本编辑器创建脚本内容。(2)使用“chmod”命令设置脚本的可执行属性。(3)执行脚本。6.2创建和执行shell程序一个合法的shell脚本程序,都是以如下图所示的shell解释器声明开始的,即在shell程序的第一行。其中“#!”后面的“/bin/bash”,表示实际使用的解释器。例如,以perl作为shell解释器,则可以该声明可以是“/usr/bin/perl”。shell解释器声明注意:与其他行不同,这里前面虽然以“#”开头,但不是注释行。6.2创建和执行shell程序在5.3.4节中,我们介绍了使用Linux的命令批量建立用户账号的方法,下面以此应用为例介绍如何创建和执行shell脚本程序。1创创建shell程序在RedHat Linux 9的命令提示符下使用gedit addusers.sh或vi addusers.sh,创建文本文件addusers.sh.,在系统打开的文本编辑窗口中输入如下的语句(其中行首编号除外)。输入完毕后保存退出。1#!/bin/sh2 if -f$1 ;then3 if -f$2 ;then4 /usr/sbin/newusers$15 /usr/sbin/pwunconv6 /usr/sbin/chpasswd$27 /usr/sbin/pwconv6.2创建和执行shell程序8 echo the users add successfully!9 else10 echo the password file does not exist!11 exit 212 fi13else14 echo the username file does not exist!15 exit 116fi第一行表示这是一个shell脚本文件,其内容由/bin/sh程序来解释执行。第二行到第八行表示当该shell程序执行时,如果从命令行中接受的两个文件存在,就执行添加用户的步骤,并给出“the users add successfully!”提示。否则给出文件不存在的提示。6.2创建和执行shell程序2设设置addusers.sh文件的可执执行属属性addusers.sh文件编辑完毕并保存后,在命令提示符下执行如下命令,设置其可执行的属性(假设addusers.sh文件保存在/root目录下)。rootmyhost root#chmod a+x addusers.sh3执执行addusers.sh脚本shell脚本的执行方法也很简单,只需要在命令提示符下输入如下命令即可:rootmyhost root#./addusers.sh account.txt password.txt其中account.txt是用户账号文件,password.txt是用户口令文件。6.3 shell环境变量及设置文件 6.3.1 shell的环环境变变量在Linux的shell中使用的变量分为以下环境变量、内部变量和用户变量3类。环境变量是Linux系统环境的一部分,通常不需要用户去定义。shell使用环境变量来存储系统信息,这些变量可以提供给在shell中执行的程序使用,不同的shell会有不同的环境变量及其设置的方法。内部变量是由系统提供的,用户不能修改它们。用户变量是用户在编写shell脚本的时候定义的,可以在shell脚本中任意使用和修改。提示:如果希望一个用户定义的变量能够在定义它的shell脚本以外使用,就必须使用export命令。例如,“export var”命令就是将用户定义的变量var添加到系统变量列表中,这样就可以在定义var变量脚本以外的地方使用。6.3 shell环境变量及设置文件 6.3.1 shell的环环境变变量在Linux的bash中可以使用set命令来查看系统当前的环境变量及其取值。如下图所示。查看Linux的环境变量说明:由于Linux的环境变量很多,这里利用管道符和tail命令与set命令结合只显示系统环境变量的最后10个。6.3 shell环境变量及设置文件 6.3.1 shell的环环境变变量若要查看当前某个环境变量的值,可以使用echo命令,并在环境变量的前面加上“$”即可。例如,查看当前的命令主提示符,可以输入如下命令:rootmyhost root#echo$PS1结果如下图所示。查看环境变量PS1命令主提示符是Linux的shell程序为用户输入命令而设置的提示符。环境变量PS1的值就是命令主提示符,默认为“uh W$”,其中“”、“”和“”原样显示;6.3 shell环境变量及设置文件 6.3.1 shell的环环境变变量“u”相应位置显示当前登录的用户账号;“h”表示相应位置显示主机名;“W”相应位置当前工作目录;“$”表示如果当前登录账号是超级用户就显示“#”,如果是普通用户就显示“$”。例如,当超级用户登录myhost主机时,命令提示符显示为“rootmyhost root#”。环境变量PATH记录了命令执行时的默认的搜索路径,即当用户在命令提示符后输入命令时,Linux系统会按照PATH设置的路径搜索该命令,然后再执行该命令。PATH变量的值由多个路径组成,各路径之间使用“:”隔开。6.3 shell环境变量及设置文件 6.3.2 shell配置文件6.3.2 shell配置文件用户可以通过set命令来查看和设置常用的环境变量,但是在系统启动的时候,Linux并不是通过set命令来设置这些变量的,而是通过读取相应的shell配置文件来获取环境变量的值的。在Linux的bash中其配置文件有全局的配置文件,也有用户个人的配置文件,shell在检查这些文件的时候,遵循如下的顺序:/etc/profile/.bashrc_profile/.bashrc/etc/bashrc。其中/etc/profile和/etc/bashrc文件中包含了全局环境变量的设置,/.bashrc_profile和/.bashrc文件中包含了个人环境变量的设置。6.3 shell环境变量及设置文件 6.3.2 shell配置文件1./etc/profile文件etc/profile文件是系统登录时最先检查执行的shell配置文件,也是Linux系统最主要的shell配置文件,有关系统最重要的环境变量都在此定义,如当前系统的PATH、USER、LOGNAME、MAIL和HOSTNAME等。在该文件中还定义了每个shell所能执行的程序的数目,即ulimit变量,以免shell过度占用系统资源。另外,在/etc/profile文件末尾会自动执行/etc/profile.d目录下的所有*.sh脚本。2./.bashrc_profile每个系统用户的子目录下都有一个.bashrc_profile文件,用于设置每个用户的bash环境变量,Linux系统启动时,在读取/etc/profile文件的内容之后,就会检查该文件。6.3 shell环境变量及设置文件 6.3.2 shell配置文件在该文件中,首先读取并执行/.bashrc文件,然后设置PATH、BASH_ENV和USERNAME的值。此处的PATH变量的值,除了在全局环境配置文件/etc/profile文件中设置的PATH的值以外,还添加了用户主目录下的bin目录。BASH_ENV的值则是接下来需要检查的文件的名称。3./.bashrc在读取/.bashrc_profile文件的过程中,Linux会在执行/.bashrc_profile文件的内部中调用并执行/.bashrc文件。另外,与前面两个文件不同,Linux系统每次用户登录bash的时候都会读取/.bashrc文件,并重新设置该文件中定义的环境变量。而/etc/profile和/.bashrc_profile只在系统启动的时候才读取。6.3 shell环境变量及设置文件 6.3.2 shell配置文件在/.bashrc文件中只定义了某些别名命令和虚拟终端的设置。例如,如果telnet登录时,无法浏览超过一页的信息或文件内容,此时可以在该文件中添加如下行:export TERM=vt100另外在该文件的最后还检查/etc/bashrc文件是否存在,如果存在则转而读取并执行该文件。4./etc/bashrc和/.bashrc文件一样,用户每次登录Linux系统的时候,都会自动读取并执行该文件。在该文件中设置了系统创建文件时默认的文件存取权限的掩码umask的值和用户自定义的命令提示符PS1。6.3 shell环境变量及设置文件 6.3.2 shell配置文件除了上面介绍的常用的环境变量配置文件以外,还有/.bash_login、/.profile、/.bash_logout和/.bash_history文件,用于系统环境变量的定义。如果/.bash_profile文件不存在时,系统会转而读取/.bashrc文件。该文件在每次用户登录时都会被bash读取并执行。通常可以将用户登录后必须执行的命令存放在这个文件中。如果/.bash_profile和/.bash_login文件都不存在的情况下,系统会使用/.profile文件中的内容设置当前环境变量的值,其功能与/.bash_profile文件完全相同。Linux系统在注销前,bash会读取并执行/.bash_logout。通常该文件中只有一个clear清屏命令。如果希望在系统注销前执行一些特定的任务,就可以将相应的命令行写入该文件。/.bash_history文件用于记录当前用户在登录系统后所执行过的命令。6.4 shell脚本编程 6.4.1 shell变变量shell脚本程序,简称shell脚本或shell程序,是使用系统提供的命令编写的文本文件,该文件具有可执行的属性,能够帮助系统管理员自动管理系统。在Linux的发行版本中就包含了很多的shell程序,这些脚本有的是为了完成系统参数的设置,例如前面介绍的/etc/profile等文件;有的是为了完成某项系统服务的启动工作,例如/etc/rc.d/init.d目录下的所有脚本。6.4.1 shell变变量shell程序语法和其他高级语言程序类似,包括变量、控制结构和函数等。6.4 shell脚本编程 6.4.1 shell变变量1.变变量类类型与与使用bash脚本是一种弱类型的脚本语言。所谓弱类型脚本语言,就是在bash脚本中,对类型的要求不严格,同一个变量可以随着使用场合的不同,存储不同类型的数据。弱类型语言变量使用灵活,但是编程者需要注意对变量当前存储的数据类型的检查。1)变量的声明在bash中,变量的使用不需要显式的声明,或者说赋值就可以认为是变量的声明。通常,给一个变量赋值应采用如下的格式:变量名=值注意:等号两边不能存在分隔符(包括空格,制表位和回车符)。6.4 shell脚本编程 6.4.1 shell变变量例如:a1=hellob1=902)变量的引用通常,要引用一个变量,可以采取在变量名前加一个$的方法,即“$变量名”。例如,要引用上面定义的变量a1可以采用如下的方法:echo a1 is$a1但是,有时候这种方法会产生混淆。例如,希望使用变量a1来输入“hello Linux”字符串。如果使用echo“$a1Linux”就会得不到期待的字符。这是因为bash把“a1Linux”作为一个变量来处理了。此时可以选择使用以下的几种用法(其中,value代表一个变量可能取的具体的值):6.4 shell脚本编程 6.4.1 shell变变量$变量var:-value:如果指定的变量var存在,则返回var的值,否则返回value。$变量var:=value:如果指定的变量var存在,则返回var的值,否则先将value赋给var,然后再返回value。$变量var:+value:如果指定的变量var存在,则返回value,否则返回空值。$变量var:?value:如果指定的变量var存在,则返回该var的值,否则将错误提示消息value送到标准错误输出并退出shell程序。$变量var:offset:length:offset和length是整数,中括号表示可选部分。表示返回从变量var的第offset+1个字符开始长度为length的子串。如果中括号部分省略,则表示返回变量var第offset+1个字符后面的子串。6.4 shell脚本编程 6.4.1 shell变变量例6-1 演示bash中变量的使用。如图下所示。各行的说明如下:bash变量的使用rootmyhost root#var=hello定义变量var,并被赋值为“hello”6.4 shell脚本编程 6.4.1 shell变变量rootmyhost root#echo$var$title:-marry!hello marry!变量title在前面都没有被赋值,所以$title:-marry返回“marry”。rootmyhost root#echo$var$title:+tom!hello!变量title仍然没有被赋值,即不存在,所以$title:+tom返回空值。rootmyhost root#echo$var$title:?title is null or empty!bash:title:title is null or empty变量title仍然没有被赋值,即不存在,所以$title:?title is null or empty返回了错误信息,即“bash:title:title is null or empty”。6.4 shell脚本编程 6.4.1 shell变变量rootmyhost root#echo$var$title:=tom and marry!hello tom and marry!到此为止变量title仍然没有被定义,所以title被赋值为“tom and marry”,并返回该值。rootmyhost root#echo$var$title:+somebody!hello somebody!此时变量title已经存在,故返回“somebody”。rootmyhost root#echo$var$title:8:5!hello marry!此处变量title已经存在,且值为tom and marry,取其第9个字符,即“m”开始后面5个字符,也就是“marry”。6.4 shell脚本编程 6.4.1 shell变变量3)特殊变量在shell程序中存在一些特殊变量,当shell程序运行时,这些变量能够记录shell程序的命令行参数。这些变量分别是$0、$1、$n,以及$#、$*和$。其中$0存放的是命令行的命令名,$1存放的是命令行中传递给命令的第一个参数,依次类推,$n存放的是传递给命令的第n个参数。$#存放传递给命令的参数的个数(不包括命令),$*和$均用于存放传递给命令的所有参数,两者的区别在于$*把所有的参数作为一个整体,而$则把所有的参数看作是类似于字符串数组一样,可以单独访问这些参数。2.shell表达达式和高级程序语言一样,shell程序的表达式由运算符和参加运算的操作数构成。操作数通常可以是变量、常量。6.4 shell脚本编程 6.4.1 shell变变量1)shell的运算符shell的运算符的使用规则都与C语言非常类似。2)shell表达式利用运算符将变量或常量连接起来就构成了表达式。但是由于在bash中变量和常量没有特定的数据类型,因此在bash中单纯使用一个表达式作为命令或语句是错误的,而必须使用expr或let命令来指明表达式是一个运算式。expr命令会先求出表达式的值,然后送到标准输出显示。let命令会先求出表达式的值,然后赋值给一个变量,而不显示在标准输出上。expr和let命令的使用方法如下:expr let 表达式2.6.4 shell脚本编程 6.4.1 shell变变量expr命令一次携带一个表达式,let命令一次可以携带多个表达式。在expr命令的表达式中使用了数值运算,此时需要用空格将数字运算符与操作数分隔开。另外,如果表达式中的运算符是“”、“&”、“*”及“|”等特殊符号,需要使用双引号、单引号括起来,或将反斜杠()放在这些符号的前面。而let命令中的多个表达式之间需要空格隔开,而表达式内部无需使用空格。例如如下几个表达式:expr 3+2操作数3、2和运算符+之间没有空格,此时bash不会报错,而是把3+2作为字符串来处理。expr 3+2操作数3、2和运算符+之间有空格,此时bash认为是数字运算,返回5送到标准输出设备。6.4 shell脚本编程 6.4.1 shell变变量 expr 3*2使用双引号将操作符*括起,此时bash返回乘积6。let s=(2+3)*4s结果为5*4=20。3条条件判断断在编写程序的时候,经常需要根据某个条件的测试进行程序执行分支的选择。这里的条件可能是某个表达式的值、文件的存取权限、某段代码的执行结果,或者是多个条件结果按照逻辑运算后的值。条件测试的结果只有真或假2种。需要注意的是,这里“真”的数值表示为0,“假”的数值表示为非0,与表达式的真值以及C语言的真值刚好相反。6.4 shell脚本编程 6.4.1 shell变变量在bash中条件测试的使用方法是,利用test命令或一对中括号包含条件测试表达式,这两种方法是等价的。它们的格式如下:test cond_expr或 cond_expr 注意:利用一对中括号时,左右的中括号与表达式之间都必须存在空格。cond_expr是需要测试的条件表达式,可以是以下几种情况:(1)文件存取属性测试:包括文件类型,文件的访问权限等。(2)字符串属性测试,包括字符串长度,内容等。(3)整数关系测试,包括大小比较,相等判断等。(4)上述3种关系通过逻辑运算(与、或、非)的组合。6.4 shell脚本编程 6.4.1 shell变变量例6-2 练习使用文件测试命令。利用shell提供的文件测试命令,测试文件的属性,如下图所示。文件属性测试首先使用test命令测试test.sh是否存在其可写,从ls l命令返回的结果看,确实是test.sh文件存在且可写的,所以“echo$?”命令返回0表示真。然后又使用中括号测试6.4 shell脚本编程 6.4.1 shell变变量tdir是不是目录以及是否可写,从ls l命令的返回来看,tdir同样是目录且可写的,所以返回真。其中“$?”表示引用变量“?”,而变量“?”是一个特殊变量,可以返回紧邻的前驱命令的返回值。例6-3练习使用字符串测试命令利用shell提供的字符串测试命令,字符串测试,如下图所示。字符串测试6.4 shell脚本编程 6.4.1 shell变变量例中首先定义了root_home变量,值为/root,变量tom_home,值为/home/tom,然后测试这两个字符串变量的值是否相等,结果为1表示不相等。例6-4练习使用数值关系测试命令。数值关系测试,如下图所示。数值关系测试6.4 shell脚本编程 6.4.2 shell控制结构结构首先定义变量var1,值为200,变量var2,值为300,接着测试var1的值是否等于var2的值。返回值为1,表示这两个变量不等。然后又测试var1是否小于var2,返回值为0,表示var1的值小于var2。6.4.2 shell控制结构结构shell程序的控制结构是用于改变shell程序执行流程的结构。在shell程序的执行过程中可以根据某个条件的测试值,来选择程序执行的路径。在shell程序中,控制结构可以简单地分为分支和循环结构2类。bash支持的分支结构有if结构和case结构,支持的循环结构有for结构、while结构和until结构。它们的使用方法与C语言等高级程序设计语言中相应的结构类似。6.4 shell脚本编程 6.4.2 shell控制结构结构1.if分支结构结构if结构是最常用的分支结构,其格式如下:if 条件测试1;thencommand_list_1elif 条件测试2;thencommand_list_2 elsecommand_list_3 fi6.4 shell脚本编程 6.4.2 shell控制结构结构其中,中括号部分为可选部分。当“条件测试1”为真时,执行command_list_1,否则如果存在elif语句,则测试“条件测试2”,如果为真,执行command_list_2。如果elif语句不存在或“条件测试2为假,则执行command_list_3。条件测试部分一般可以是test或修饰的条件表达式。例6-5 根据用户输入的目录名称判断该目录是否存在,如果存在则进入该目录,否则测试同名文件是否存在,如果存在,则退出shell程序,否则新建同名目录,并进入该目录。#!/bin/bash#an example script of ifclearecho input a directory name,please!6.4 shell脚本编程 6.4.2 shell控制结构结构read dir_name#测试$dir_name目录是否存在if d$dir_name ;thencd$dir_name /dev/null 2$1echo$dir_name has already existed,enter directory succeed#测试是否存在与$dir_name同名的文件elif -f$dir_name ;thenecho file:$dir_name has already existed,create directory failedexit6.4 shell脚本编程 6.4.2 shell控制结构结构elsemkdir$dir_name /dev/null 2$1cd$dir_nameecho$dir_name has not existed,create and enter directory succeedfi在该例中,“cd$dir_name /dev/null 2$1”表示cd命令可能产生的标准输出信息和标准错误输出信息重定向的到一个空设备/dev/null,从而实现隐藏cd命令错误输出的功能。“mkdir$dir_name /dev/null 2$1”命令行的作用类似。由于Linux不允许在同一目录下存在同名的文件和目录,所有如果$dir_name不存在时,还要测试是否有同名的文件存在,然后才能新建该目录。6.4 shell脚本编程 6.4.2 shell控制结构结构注意:then命令可以和if结构写在同一行,但是如果then命令和if结构在同一行时,then命令的前面一定要有一个分号,且分号与条件测试表达式之间用空格隔开。2.case分支结构结构if结构用于存在两种分支选择的情况下,当程序存在多个分支的选择时,如果使用if结构,就必须使用多个elif结构,从而使得程序的结构冗余,此时可以选在使用case结构。case结构可以帮助程序灵活地完成多路分支的选择,而且程序结构直观、简洁。case分支结构的格式如下:case expr模式1)6.4 shell脚本编程 6.4.2 shell控制结构结构command_list_1;模式2)command_list_2;*)command_list_n;esac其中,expr可以是变量、表达式或shell命令等,模式为expr的取值。通常一个模式可以是expr的多种取值,使用或(|)连接。模式中还可以使用通配符,星号(*)表示匹6.4 shell脚本编程 6.4.2 shell控制结构结构配任意字符值,问号(?)表示匹配任意一个字符,.可以匹配某个范围内的字符。在case分支结构中,首先计算expr的值,然后根据求得的值查找匹配的模式,接着执行对应模式后面的命令序列,执行完成后,退出case结构。需要注意的是,在case结构的命令序列后面需要使用双分号(;)分隔下一个模式。例6-5 使用case语句编写程序,根据上网地址的不同为计算机设置不同的IP地址参数。#!/bin/bash#an example script of caseclearecho please enter current location(home,h,H,office,o,O):6.4 shell脚本编程 6.4.2 shell控制结构结构read nettypecase$nettype in home|h|H)/sbin/ifconfig eth0 192.168.0.118 netmask 255.255.255.0 /sbin/route add default gw 192.168.0.1 ;office|o|O)/sbin/ifconfig eth0 192.168.1.58 netmask 255.255.255.0 /sbin/route add default gw 192.168.1.1 ;6.4 shell脚本编程 6.4.2 shell控制结构结构 *)echo input error!exit ;esacecho“Success!”本例程中,如果用户输入home、h或H则表示上网地点是在家中,此时IP地址为192.168.0.118,网络掩码为24,默认网关为192.168.0.1。如果用户输入office、o或O则表示上网地点是在办公室内,此时IP地址为192.168.1.118,网络掩码为24,默认网关为192.168.1.1。其他的输入无效,并给出提示“input error!”。其中ifconig和route命令在后面的章节中将详细介绍。6.4 shell脚本编程 6.4.2 shell控制结构结构3.for循环结构环结构for循环用于预先知道循环执行次数的程序段中,它是最常用的循环结构之一。for的格式如下:for var in value_list docommand_listdone其中,value_list是变量var需要取到的值,随着循环的执行,变量var需要依次从value_list中的第一个值,取到最后一个值。do和done结构之间的command_list是循环需要执行的命令序列,变量var每取一个值都会循环执行一次command_list中的命令。同样中括号部分为可选部分,如果省略了该部分,bash会从命令行参数中为var取值,即等同于“in$”。6.4 shell脚本编程 6.4.2 shell控制结构结构例6-6 使用for语句编写程序,向系统添加10个用户,其名称分别是student1、student2、student10。#!/bin/bash#an example script of forfor i in 1 10 doif -d/home/student$i ;thenecho the directory/home/student$i exist.echo the content of directory/home/student$i is moved to/home/stu$imv student$i stu$i6.4 shell脚本编程 6.4.2 shell控制结构结构fiadduser student$i /dev/null 2$1echo student$i|passwd usr$i$j-stdinecho user add succeed,the home directory is:/home/student$idone由于在Linux中adduser命令会在/home目录下创建与用户同名的子目录作为用户的主目录,所以,该例程首先检查/home目录下是否存在与student1、student2、.student10同名的子目录,如果存在则将其重命名为stu1、stu2、stu10,然后在执行创建用户的任务,并且用户的初始口令与用户名相同。6.4 shell脚本编程 6.4.2 shell控制结构结构4.while和until循环结构while和until循环结构的功能基本相同,主要用于循环次数不确定的场合。while的格式如下:while exprdocommand_listdoneuntil的格式如下:until exprdocommand_listdone6.4 shell脚本编程 6.4.2 shell控制结构结构从格式上看,二者的使用方法完全相同,但是二者对循环体执行的条件恰恰相反。在while循环中,只有expr的值为真时,才执行do和done之间的循环体,直到expr取值为假时退出循环。而在until循环中,只有expr的值为假时,才执行do和done之间的循环体,直到expr取值为真时退出循环。从上面的while和until循环的执行流程可以看出,expr的取值直接决定command_list的执行与否以及能否正常退出循环,因此通常在命令序列command_list中都存在修改expr取值的命令。否则while和until就无法退出command_list的执行循环,从而陷入死循环。通常,同一个问题如果可以使用while循环,就可以使用until循环。例6-7 while和until循环结构示例。6.4 shell脚本编程 6.4.2 shell控制结构结构上面两段程序都是完成对循环变量loop加1的任务,两段程序的输出结果完全相同。对比两个程序可以发现,只有循环条件的设置不同。while循环示例until循环示例#!/bin/bash#an example script of whileclearloop=0#!/bin/bash#an example script of untilclearloop=0while$loop le 10 until$loop gt 10 do let loop=$loop+1 echo the loop current value is:$loopdonedo let loop=$loop+1 echo the loop current value is:$loopdone6.4 shell脚本编程 6.4.3 shell函数数6.4.3 shell函数数和其他的高级程序设计语言一样,在bash中也可以定义使用函数。函数是一个语句块,它能够完成独立的功能,而且在需要的时候可以被多次使用。利用函数,shell程序将具有相同功能代码块提取出来,实现程序代码的模块化。在程序需要修改的时候,只需要修改被调用的函数,减少了程序调试和维护的强度。在bash中,函数需要先定义后使用。函数定义的格式如下:function fun_name()command_list6.4 shell脚本编程 6.4.3 shell函数数其中,function表示下面定义的是一个shell函数,可以省略。fun_name就是定义的函数名。command_list就是实现函数功能的命令序列,称为函数体。函数一旦定义就可以被多次调用,而且函数调用的方法与shell命令的方法完全一致。函数调用的格式如下:fun_name param_1 param_2 param_n其中,fun_name是被调用的函数名,param_1、param_2、param_n是调用时传递给函数的参数,各参数之间使用空格隔开。函数调用时是否需要传递参数,由函数的定义和功能决定。如果函数确实需要传递参数,此时可以使用$0、$1、$n,以及$#、$*和$这些特殊变量。其中$0存放的是命令行的命令名(也就是执行的shell脚本名),$1存放的是命令行中传递给命令的第一个参数,依次类推,6.4 shell脚本编程 6.4.3 shell函数数$n存放的是传递给命令的第n个参数。$#为传递给命令的参数的个数(不包括命令),$*和$均用于存放传递给命令的所有参数,两者的区别在于$*把所用的参数作为一个整体,而$则把所有的参数看作是类似于字符串数组一样,可以单独访问这些参数。例6-8 向bash函数传递参数的示例。在bash脚本中定义函数,然后在该脚本时通过命令行传递参数。#!/bin/bash#an example script of function#fun1函数定义function fun1()echo Your command is:$0$*6.4 shell脚本编程 6.4.3 shell函数数echo Number of parameters($#)is:$#echo Script file name($0)is:$0echo Parameters($*)is:$*echo Parameters($*)is:$*count=1for param in$doecho Parameters($co
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 成人自考


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!