admin 管理员组

文章数量: 887021


2023年12月23日发(作者:linux 命令cp)

三、预备知识二、实验内容一、实验目的五、实验原理及说明变量的定义及其使用。2.位置参数和环境变量。中的特殊字符。4.条件判断结构与循环结构5.函数的定义和使用了解 Shell 的作用和主要分类。了解 Bash的一般语法规则。练习编写简单的shell程序。软件:PC机操作系统REDHAT ELAS4环境四、实验设备及工具1、LINUX环境下常用命令和VI编辑器的操作。2、了解Shell作用和主要分类等基础知识。Shell编程实验Shell是Linux系统中一个重要的层次,它是用户与系统交互作用的界面。在介绍Linux命令时,Shell都作为命令解释程序出现:它接收用户打入的命令,进行分析,创建子进程实现命令所规定的功能,等子进程终止工作后,发出提示符。这是Shell最常见的使用方式。Shell 除了作为命令解释程序以外,还是一种高级程序设计语言,它有变量,关键字,有各种控制语句,如 if, case, while, for 等语句,有自己的语法结构。利用Shell程序设计语言可以编写出功能很强、但代码简单的程序,特别是它把相关的Linux命令有机地组合在一起,可大大提高编程的效率,充分利用Linux系统的开放性能,设计出适合自己要求的命令。

1.语法练习六、实验步骤(1)Shell变量

$ dir=/usr/mengqc/file1$ echo $ dir/usr/mengqc/file1

$ echo dirdir$ today=Sunday$ echo $ today $ TodaySunday$ str="Hapy New Year ! "$ echo "Wish You $str"Wish You Happy New Year !

Shell有两种变量:环境变量和临时变量。在Shell脚本中临时变量又分为两类:用户定义的变量和位置参数。用户定义的变量用户定义的变量是最普遍的Shell变量,变量名是以字母或下化线打头的字母、数字和下线符序列,并且大小写字母意义不同。变量名的长度不受限制。定义变量并赋值的一般形式是: 变量名=字符串 例如,

MYFILE=/usr/meng/ff/.定义并显示变量的值在程序中使用变量的值时,要在变量名前面加上一个符号“$”。这个符号告诉Shell,要读取该变量的值。练习1.1:命令作为交互式输入手段,可以利用read命令由标准输入(即键盘)上读取数据,然后赋给指定的变量。其一般格式是:read 变量1 [变量2...]练习1.2:$ read name -----输入read命令mengqc -----输入name的值$ echo "Your Name is $ name."Your Name is mengqc -----显示输出的结果$ read a b c -----read命令有三个参数crtvu cn edu -----输入三个字符串,中间以空格隔开$ echo "Email : $a. $c. $b"

Email : -----显示输出结果

利用read命令可交互式的为变量两赋值。输入数据时,数据间以空格或制表符作为分隔符。注意以下情况:*若变量个数与给定数据个数相同,则依次对应赋值,如上面例子所示。*若变量数少于数据个数,则从左至右依次给变量赋值,而最后一个变量取得所有余下数据的值。

文件ex3:$ chmod +x ex5$ chmod +x ex3*若变量个数多余给定数据个数,则从左到右依次给变量赋值,后面的变量没有输入数据与之对应时,其值就为空串。位置参数执行Shell脚本时可以使用参数。由出现命令行上的位置确定的参数称做位置参数。在sh中总共有十个位置参数,其对应的名称依次是$0,$1,$2,...$9。其中$0始终表示命令名或Shell脚本名,对于一个命令行,必然有命令名,也就必定有$0;而其它位置参数依据实际需求,可有可无。练习1.3 位置参数的作用。a.在你的计算机上建立以下三个文件(设建立在目录/usr/username之下,其中username表示你的主目录名):文件m1.c:c.利用env命令查看在环境变量PATH中是否包含你的当前工作目录(即/usr/use-name)。如果没有包含在其中,则利用以下语句改变PATH的值:$ PATH= $ PATH:/usr/usr/usernamed.执行脚本ex3:$ ex5 m1.c m2.c10$ ex3 m1.c m2.c10c.执行脚本ex5:main( ){printf("Begin n");}文件m2.c:# include < stdio.h >{printf("OK! n");}n1=$1n2=$2n3=$3cat $n1 $n2 $n3 | wc -lb.将ex5改为具有执行权限:b.将ex3改为具有执行权限:练习1.4 利用位置参数给定变量赋值。a.建立脚本ex5,如下所示:# ex3: shell script to combine files and count linescat $1 $2 $3 $4 $5 $6 $7 $8 $9 | wc -l# end

(2)Shell中的特殊字符

通配符通常的通配符有三种:* 星号,它匹配任意字符的0次或多次出现。但注意,文件名前面的圆点(.)和路径名中的斜线(/)必须显示匹配。 问号,它匹配任意一个字符。[] 一对方括号,其中有一个字符组。其作用是匹配该字符组所限定的任意一个字符。应该注意:字符 * 和 ?在一对方括号外面是通配符,若出现在其内部,它们就失去通配符的能力了。! 叹号,若它紧跟在一对方括号的左方括号[之后,则表示不在一对方括号中所列出的字符。引号在Shell中引号分为三种:单引号、双引号、和倒引号。双引号由双引号括起来的字符,除$、倒引号和反斜线()仍保留其功能外,其余字符通常作为普通字符对待。练习1.5a.建立以下文件ex8:(3)条件判断与循环结构

$sh ex8b.执行ex8:echo"current directory is`pwd`"echo"home directory is $ HOME"echo"file * . ?"echo" directory ' $ HOME ' "单引号由单引号括起来的字符都作为普通字符出现。倒引号练习1.6:反斜线转义字符,若想在字符串中使用反斜线本身,则必须采用()的形式,其中第一个反斜线作为转义字符,而把第二个反斜线变为普通字符。

又:$ users=`who | wc -l`$ echo The number of users is $ usersThe number of users is 5$ today=`date`$echo Today is $ todayToday is Thu May 04 10 :56 :20 CST 2000$if 语句

b.执行ex9:练习1.7a.建立脚本ex9:如上例改写成为:$sh ex9 ex1The current directory is /usr/mengqcex1 is anordinary file.测试语句:有两种常用形式:一种是用test命令,如上所示。另一种是用一对方括号将测试条件括起来。两种形式完全等价。例如,测试位置参数$1是否是已存在的普通文件,可写成:test -f " $1",也完全可写成:[ -f $ l ]在格式上应注意,如果在test语句中使用shell变量,为表示完整、避免造成歧异起见最好用双引号将变量括起来。利用一对方括号表示条件测试时,在左方括号[之后、右方括号]之前各应有空格。练习1.8a.建立脚本文件ex10echo "The current directory is `pwd`"if test - f " $1"then echo " $1 is an ordinary file."else echo " $ 1 is not anordinary file."fiif test -f " $1"then cat $1elif test -d " $1"then ( cd $1 ; cat * )else echo " $1 is neither afile nor adirectory."fiif test - f " $1"then cat $1else if test - d " $1"then ( cd $1 ;cat * )else echo "$1 is neither a file nor a directory."fifiif语句的else部分还可以是else-if结构。 (wj14)echo "Enter your filename"

read filenaneif [ -f " $filename"]then cat $ filenameelse if [ -d " $ filename"]then cd $ filenamels -l *else echo " $ filename:bad filename"

fifi

$sh ex10b.执行ex10while语句练习1.9a.建立脚本ex11:练习1.12a.建立脚本ex13:b.执行ex11练习1.10a.建立脚本ex12:echo"ley in file->c"read filenameecho"key in data:"while [n $x]do

read xecho $x>>$ filenamedonecat $ filenameb.执行ex12,并分析结果。for语句练习1.11while [ $1 ]

do

if [ -f $1 ]then echo "display : $1"cat $1else echo " $1 is not a file name."fishiftdone# display files under a given directoryfor day in Monday Wednesday Friday Sundaydoecho $ daydone例如: (wj20)for file in m*.cdocat $ file | moredone

(4)函数的定义与调用

funcname()

{

command

...

command; #分号

}

b.执行ex13,并分析运行结果。# $1-the nameof the diectory# $2-the of filesdir=$1;shiftif [ - d $ dir ]then

cd $dirfor namedoif [ -f $name ]then cat $nameecho "End of $ {dir} / $name"else echo "Invalid file name: $ {dir} / $name"fidoneelse echo "Bad directory name : $dir"fi$同其他高级语言一样,shell也提供了函数功能。其定义格式如下:

定义函数之后,可以在shell中对此函数进行调用

如下所示:

iscontinue()

{

while true

do

echo -n "Continue?(Y/N)"

read ANSWER

case $ANSWER in

[Yy]) return 0;;

[Nn]) return 1;;

*) echo "Answer Y or N";;

esac

done

}

if iscontinue

then

continue

else

break

fi

# Cleanup, 版本 2cd /var/log cat /dev/null > messagescat /dev/null > wtmp echo "Logs cleaned up."2.综合实验一:清除/var/log 下的log 文件echo "Logs cleaned up."cat /dev/null > messagescat /dev/null > wtmp#!/bin/bash# 一个Bash 脚本的正确的开头部分.LOG_DIR=/var/log# 如果使用变量,当然比把代码写死的好.cd $LOG_DIR练习2.1 版本1在一个最简单的例子中,一个shell 脚本其实就是将一堆系统命令列在一个文件中。好处就是把所有命令都放在一个脚本中,不用每次都敲它们.这样的话,对于特定的应用来说,这个脚本就很容易被修改或定制。在这次练习中,我们编写一个最简单的脚本,其内容是用两条命令清除/var/log/message和/var/log/wtmp中的内容。

练习2.2 版本2下面按照Shell编程的一些规则进行改良:在第一行添加一个Bash 脚本的正确的开头部分,指定解释器为bash。使用变量指定/var/log目录,在后面使用这个变量。最后用exit退出。使用注释说明各部分的用法。exit # 这个命令是一种正确并且合适的退出脚本的方法.这样可以在shell编程中调用iscontinue确定是否继续执行:

# 当然要使用root 身份来运行.# 在此处插入代码,来打印错误消息,并且在不是root 身份的时候退出.

#!/bin/bash练习2.3 版本3现在,让我们来编写有真正意义的脚本:添加权限有关语句,判断执行脚本的是否根用户,如果不是则输出出错信息,退出。添加语句,判断是否有命令行参数,如果有,假设是n,在后面的清除log的时候保留最后的n行;如果没有,设n=50。你可以不断地找到新的方法来完善这个脚本,并提高效率。cd $LOG_DIR# 一定要使用根用户来运行if [ "$UID" -ne "$ROOT_UID" ]then echo "Must be root to run this script." exit $E_NOTROOTfi

if [ -n "$1" ] # 测试是否有命令行参数(非空).then lines=$1else

lines=$LINES # 如果不在命令行中指定,使用默认fi

################################################################ 说明:删除logfile 的脚本###############################################################LOG_DIR=/var/logROOT_UID=0 # $UID 为0 的用户才具有根用户的权限LINES=50 # 默认的保存行数E_XCD=66 # 不能修改目录,与下面的E_NOTROOT相似,用于本脚本退出返回E_NOTROOT=67 # 非根用户# 可以使用下边的更好方法来检测命令行参数.# 其使用了case结构## E_WRONGARGS=65 # Non-numerical argument (bad arg format)## case "$1" in# "" ) lines=50;;# *[!0-9]*) echo "Usage: `basename $0` file-to-cleanup"; exit $E_WRONGARGS;;# * ) lines=$1;;# esac#

cat /dev/null > wtmpecho "Logs cleaned up."exit 0# 退出之前返回0,表示成功.3.综合实验二:找出死链接文件#!/bin/bash# #WrittenbyLeebigelow<********************># Modified and commented by oyxin# Used with permission.执行流程:1.判断是否有命令行参数,如果没有,那么就使用当前目录,否则就使用传递进来的参数作为目录来搜索。2.建立函数linkchk,用来检查传进来的目录或文件是否是链接和是否链接到不存在的路径,即死链接。如果是死链,打印出它们的路径。如果传进来的目录有子目录,那么把子目录也发送到linkchk 函数中处理,也就是递归目录。3.对每个从脚本传递进来的参数,都调用linkchk 函数去处理,如果有参数不是目录,那就打印出错误消息和使用信息。4.Exit退出。# 说明:用来找出死链接文件并且输出它们的路径# 更有效率的做法是:## cd /var/log || {# echo "Cannot change to necessary directory." >&2# exit $E_XCD;# }tail -$lines messages > # 保存log file 消息的最后部分.mv messages # 变为新的log 目录.if [ `pwd` != "$LOG_DIR" ] # 也可以用 if [ "$PWD" != "$LOG_DIR" ] # 查看是否在 /var/log目录中then echo "Can't change to $LOG_DIR." exit $E_XCDfi# 在处理log file 之前,再确认一遍当前目录是否正确.

exit 0for directory in $directorys; do if [ -d $directory ]then linkchk $directoryelse

echo "$directory is not a directory" echo "Usage: $0 dir1 dir2 ..." fidone[ $# -eq 0 ] && directorys=`pwd` || directorys=$@# 如果没对这个脚本传递参数,那么就使用当前目录.# 否则就使用传递进来的参数作为目录来搜索.linkchk () { for element in $1/*; do [ -h "$element" -a ! -e "$element" ] && echo "$element" [ -d "$element" ] && linkchk $element # '-h'是测试链接,'-d'是测试目录. done}###############################################################


本文标签: 变量 参数 脚本 命令 使用