shell脚本练习题_第1页
shell脚本练习题_第2页
shell脚本练习题_第3页
shell脚本练习题_第4页
shell脚本练习题_第5页
免费预览已结束,剩余18页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、shell脚本例子集锦(习题总结)练习一:写一个脚本1. 设定变量FILE的值为/etc/passwd2. 依次向/etc/passwd中的每个用户问好,并且说岀对方的ID是 什么形如:(提示:LINE二、wc -1 /etc/passwd cut -d" -fl ) Hello,root, your UID is 0.3. 统计一个有多少个用户 答案一:#! /bin/bashfile二"/etc/passwd"LINES='wc -1 $file cut -d" " -fl' for I in 、seq 1 $LINES、;

2、do userid='head -$1 $file tail T i cut -d: -f3 username= head -$1 $file : tail T cut -d: -fl' echo "hello $username, your UID is $userid,z doneecho "there are $LINES users"答案二:#! /bin/bashfile=/etc/passwdlet nunpOfor I in 'cat $file':do username二、echocut -d: -fl'us

3、erid='echo "$I" j cut -d: -f3 echo ,zHello, $username, your UID is $userid,z num=$num+ldoneecho "there are $num users" 练习二:写一个脚本1 切换工作目录至/v孔2. 依次向/var El录中的每个文件或子目录问好,形如:(提示:for FILE in /var/*;c for FILE in ' Is /var' ;) Hello, log3. 统计/var El录下共有多个文件,并显示出来 答案:#! /bin

4、/bashcd /varlet numOfor I in 'Is /var/;doecho "hello $1" num=$num+lZ doneecho "the number of files is $num"练习三:写一个脚本1. 设定变量file的值为/etc/passwd2使用循环读取文件/etc/passwd的第2, 4, 6, 10, 13, 15彳亍,并显示 其容3.把这些行保存至/tmp/mypasswd文件中答案:#! /bin/bashfile二"/etc/passwd"for I in 2 4 6 10

5、 13 15; doexec 3>/tmp/Zmypasswdline='head -$1 $file tail 1'echo "$line"echo "$line" >&3exec 3>&-done练习四:写一个脚本传递两个整数给脚本,让脚本分别计算并显示这两个整数的和, 差,积,商答案如下:vim test, sh#!/bin/bashecho "first number $1"(表示输出第一个数)echo "second number $2"(表示输出第二个数

6、)echo "$($1+$2)"(输出两数之和)echo"$1 - $2"(输出两数之差)echo(输出两数之积)echo"$1/$2"(输岀两数之商):wq(表示保存并退出Vi编辑器)chmod +x test, sh(给test, sh执行的权限)/test sh 23(传递两个参数并执行脚本作业一:写一个脚本:1.创建目录/tmp/scripts2 切换工作目录至此目录中3复制/etc/pam. d LI录至当前U录,并重命名为test4. 将当前目录的test及其里面的文件和子目录的属主改为 redhat5. 将test及其子

7、LI录中的文件的其它用户的权限改为没有任何权限答案:#!/bin/bashmkdir -v /tmp/scriptscd /tmp/scriptscp -r /etc/pamd /testchown -R redhat /testchmod -R o=/test作业二:写一个脚本1 显示当前系统日期和时间,而后创建目录/tmp/lstest2. 切换匚作目录至/tmp/lstest3. 创建目录 did, b56e, 6test4. 创建空文件xy, x2y, 7325列出当前目录下以/ x或者6开头的文件或目录6列出当前目录下以字母开头,后跟一个任意数字,而后跟任意 长度字符的文件或目录答案

8、:#!/bin/bashdatemkdir -pv /tmp/lstestcd /tmp/lstestmkdir aid b56e 6testtouch xy x2y 732Is ax6*Is :alpha:jj:digit:*作业三:写一个脚本添加10个用户userl到userlO,但要求只有用户不存在的情 况下才能添加答案:#!/bin/bashfor I in、seq 1 10、:docut d: -fl /etc/passwd grep use:r$I 2»/tmp/etc.err useradd user$Idone作业四:写一个脚本通过ping命令测试192. 168.

9、0. 151到192.168. 0. 254之间的所有 主机是否在线如果在线,就显示“ip is up”如果不在线,就显示"ip is downv答案:#!/bin/bashfor I in seq 151 254、;doping -cl -wl 192. 168. 0. $1 &>/dev/null && echo "192. 168. 0. $1is up"echo "192 168. 0$1 is down"done例题:shelll.sh显示Fl期和时间。#!/bin/bashecho current ti

10、me is 'dateM,/date 要加反引号shell2.sh显示文件名,并显示位置参数(执行时带一个参数)($0 是一个特殊的变量,它的容是当前这个Shell程序的文件名;$1是一个位置参 数,位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的$1, 第二个替换$2,依次类推。)#!/bin/bashecho "the program name is $0"$0 是一个特殊的变数echo "the first para is $lw/$1 是一个位置参数echo Mthe program exitw执行时带一个参数 如./shell2

11、.sh abedshell3.sh判断并显示位置参数#!/bin/bashif -d “$l"thenecho "$1 is directory ,existed" elseecho "$1 does not exist #now create it" mkdir $1echo “$1 is created" fi执行时带一个参数shell4.sh 问候用户#!/bin/bash user='whoami' case $user in teacher) echo "'hello teacher&quo

12、t; root) echo "hello root"*)echo "hallo $user,welcome/esac1> 求 1+2+3+.+100 的和是?#!/bin/bashSUM=O1=0while $1 -le 100 doSUM=$(SUM+l)l=$(l+l)doneecho 11 由 1+2+3+.+100 的和是:$SUM"2、(基训*一)在根目录下有四个文件ml.txt, m2.txt, m3.txt, m4.txt,用Shell编程,实现自动创建ml,m2,m3,m4四个目录,并将m 1 .txt,m2.txt,m3.txt,

13、m4.txt四个文件分别拷贝到各自相应的目录下。#!/bin/bash cd/ touch ml.txt m2.txt m3.txt m4.txt 1=1while $1 -le 4 domkdir m$lcpm$li=$(i+D)done3、(基训十二)编写一个名为myfirstshell.sh的脚本,它包括以下容。a)包含一段注释,列出您的、脚本的名称和编写这个脚本的目的。b)问候用户。C)显示日期和时间。d)显示这个月的日历。e)显示您的机器名。f)显示当前这个操作系统的名称和版本。g)显示父目录中的所有文件的列表。h)显示root正在运行的所有进程。i)显示变量TERM、PATH和HO

14、ME的值。j)显示磁盘使用情况。k)用id命令打印出您的组IDom)跟用户说"Good bye"#!/bin/bash转09嵌入5号贾德进myfirstshell.sh shell的简单编程 user='whoami'case $user inroot)echo "hello root"teacher)echo "hello teacher1'*)echo "hello $user/welcome" echo 11日期和时间:'date'"echo ”本月的日历:'c

15、al'"echo "本机的机器名:'uname -n'"echo ”当前这个操作系统的名称和版本:'uname -s;uname -r'"echo ”父目录中的所有文件的列表:'Is ./'echo "root正在运行的所有进程:' ps -u root'"echo ”变数 TERM 的值:$TERM"echo ”变数 PATH 的值:$PATH"echo "变数 HOME 的值:$HOME"echo ”磁盘的使用情况fdf

16、-echo ”用id命令打印出你的组ID:'id -g'"echo "Good bye!'14、(基训十三)设计一个Shell程序,在/userdata目录下建立50个目 录,即user!user50,并设置每个目录的权限为rwxr-xr #!/bin/bashcd /userdata1=1while $1 -le 50 domkdir -p userdata/user$lchmod o-x user$ll=$(l+l»done5、(基训十四)编写shell程序,实现自动删除50个用户账号的功能。账号名为studl至studSOo#!/bi

17、n/bashcd /userdata1=1while $1 -le 50 domkdir p userdata/user$lchmod o-x user$li=$(i+D)done 6> (基训十四)设计一个shell程序,备份并压缩/etc目录的所有容,存放在 /root/bak 录里,且文件名为如下形式yymmddetc, yy为年,mm为月,dd 为日。#!/bin/bashDIRNAME=、ls | root | grep bak if -z$DIRNAME; then mkdir/root/bak cd /root/bak fiYY=、date + %y、MM='dat

18、e + %m、DD=%date + %d'tar czvf $YY$MM$DD_etc.gz /etc echo 11 etc bak finshied"7、(基训十四)某系统管理员需每天做一定的重复工作,请按照下列要求,编 制一个解决方案:(1)在下午4:50删除/abc目录下的全部子目录和全部文件;<2)下午5:50将/data目录下的所有目录和文件归档并压缩为文件: backup.tar.gz;(3)在下午5:55将IDE接口的第二个逻辑分区卸载。/ 采用: vi pram.cron#(D在下午4:50删除/abc目录下的全部子目录和全部文件;50 16 * rm

19、 -rf/abc/*#(2)下午5:50将/data目录下的所有目录和文件归档并压缩为文 件:backup.tar.gz;50 17 * tar czvf back.tar.gz /data#(3)在下午5:55将IDE接口的第二个逻辑分区卸载.55 17 * umount /dev/hda6/ 执行:crontab pram.cron设计一个Shell程序,在/userdata目录下建立50个目录,即userluser50,并设置每个目 录的权限,其中苴他用户的权限为:读:文件所有者的权限为:读、写、执行:文件所有者 所在组的权限为:读、执行。程序实现及注释如下:#! /bin/bash#a

20、dddir.shi=l#while循环while $i -le 50 do#利用test命令-d /userdata :判断/userdata是否存在,如果存在直接创建子目录,不# 存在先创建/userdata再创建子目录。if -d /userdata then#mkdir -p的意思是:无论父目录/userdata存在与否,都会创/userdata/user$imkdir p /userdata/user$ielsemkdir /userdatamkdir p /userdata/user$ifi#根据题目的意思:/userdata/user$i应该是具有754权限,所以利用chmod赋权

21、限。chmod 754 /userdata/user$i匸 $($i+D)done函数in_path:判断传入文件是否可执行,若可执行(且存在)返回0,否则返回1:分析:为测试传入文件是否在PATH所有的目录中,需取得PATH中的每个路径,可用循环, 但需要设定环境中的分隔符(借助环境变量IFS)为PATH中的分隔符冒号":”注:$IFS输入分隔符 shell读取输入数据的时候,会把一组字符看做是单词之间的分隔字符,它们通常 是空格,制表符,和换行符.函数调用方式为:in_path filenamein_path()cmd=$l# $1为函数的参数1,以此类推retval=l#定义返

22、回值变址oldIFS=SIFSIFS=:#设宜新的IFS,并保存原來的以恢复使用for directory in $PATH#for 循环结构二:for - indoif -x airectory/$cmd ; then#if条件语句之同行表示以分号隔开retval=0# -x 判断文件有是否有可执行权限donedoneIFS=$oldIFS#恢复原來 IFS,rerurn retval)注:1 函数的结构,没有形参2 变虽的引用需要符号$,而变址的定义或赋值则不需要。3 賦值要无间隙,条件要间隙改进:1 将路径.分隔符均作为函数的参数传入.应用得到扩展。补充.in_path函数不能对绝对路径

23、的文件处理.需写个函数对这一情况的独处理 checkForCmdlnPath()var=$l#首先判断传入的非空串是否为绝对路径即检测第一个字符是不是/=如果是,直接测 if $var ! = u,/ ; then# 条件等价干 -n $varif ''$var%Svar#? ,f = Vz ; then #等价于 $(echo $var | cut -cl) if ! -x $var ) ; thenreturn 1fi#not found or not executableelif ! inpath $var ; thenreturn 2fi#not found in PA

24、THfi)注此函数让人一头雾水,详解如下:1)表达式$var%$var#?作匹配用.分解为$(var%expr $var#expr) , expr为正则表达 式(?匹配収一字符)后者(带#的)返回expr与var匹配成功位宜之后的所有容此处为var中第一字符之后的所有。 前者(带的)返回expr与var匹配成功位宜之前的所有容,此处应为var的第一个字符。等价于$ (echo $var I cut cl) 即取第一字符。等于 $ var :beginpos: sizebeginpos=Ot slz殳=1 1甘的结果。var的符号放在外面假设$var为$1,则表达式表示为2)关于if的条件判断与

25、C语言中的理解不一致,反映在上述的elif语句中的条件。理解如下: shell中的if条件可以是表达式(需加方括号门)另外还可以是命令或函数(不需方括号),肖 命令执行成功时会后继执行具体操作,经测试,C语言中所说的true在shell中用0表示,即if 0,才执行then.因为linux下的程序实现都是当返回0时表执行成功。3)若函数中没有返回值,则它默认返回0,表执行成功。函数的編写若遵从以上的原则,则对条件的理解依旧像C语言中的TRUE, FALSE 一样理解=完善程序代码=#!/bin/bashin_path() #函数实现区域 处理不路径返回0表找到.可执行.否则返回1#checkF

26、orCmdlnPath) #函数实现区域处理带路径和不带路径的返回1表没找到或不可执行返回2表没找到。默认0表找到#代码执行起始位宜 #if $# -nq 1 ) ; thenecho ''Usage: $0 command"#$0表此执行文件(具体容 以 执行此文件时的输入串为准)exit 0#调用函数并经第一个参数传给函数checkForCmdlnpath $1#对函数返回的结果进行判斯$?为函数的返回值.case $? in格式,注意红色部分。0) echo ''found in PATH,Z ;1) echo ''not fou

27、nd or not executabl殳 ;# case控制结构的类似于C语言中的2) echo ''not found" ;# default2 写一个脚木,检测用户输入串的合法性,要求串由大小写字僚、数字组成.无标点.持殊符号.空格。 思路:将输入的串中非字母数字的容删除或替换为空后若和原來输入的相同则合法,否则不合法。 IsvalidAlphaNum)compressed=/z$ (echo $1 I sed 1 s/-: alnum: /g1)/z*替换不合要求字符为空if xxScompressed/, !=; thenreturn 1# not valid

28、eelsereturn 0# validefi注:1 关于引用变虽时是否需要双引号的说明如果只是输出.可以不用双引号如果变址值代的容中无空格.表达,特殊符号,在引用时可以不需要双引号,反之.最好帯双引号. 否则在变虽:处理时很有可能会出现“参数过多"等莫名其妙的错误信息C2 关于匹配处理,sed是讯行编辑程序。sed 's/strl/str2/g file 将文件fik中每 行strl替换为str2:alnum:表示所有字母和数字中的任一个字符。若只是:alnum:则表示方括号中的任一 个字符。(-:alnum:表除了所有字母数字外的任一字符。如果是直接向脚木传字符串.则带空

29、格的字串会被脚木自行分解为藝个参数,所以可采用从标准输入读取 的方式获得字串。=完善程序代码=#!/bin/bashIsvalidAlphaNum).#函数体,判断字串的合法性echo -n uEnter input:,z# 一n 强制不换行read input#读取容存到input中,无$符号if ! isvalidAlphaNum 、'&input" ; then#加弓I号,否贝9可能会出错。echo xxinvalide,zexit 1elseecho xxvalidez,fi exit 03. 输入一个“month day year”格式的日期串,程序将处理

30、month"为 其英文单词 的前三个字母,第一个字母大写,其余的小写。思路:首先判断month是数字、还是单词,若是数字,则可查“数字一month”映射表(自 定义case结构):若是单词,则取前三个字母,并格式化。函数monthnoToName ()将month数字转换为month名monthnoToName()case $1 in1)month=H Jan1'/ /2month=HFeb”f r3)month=nMarH/ /4month="AprHf r5)month=nMayH/ /6month=" Jun1'f r7)month=HJul

31、H/ f8month="Aug"f r9)month=nSepHr r10)month="OctHr rIDmonth=,NovHr r12month=,Dec,'r r* ) echo H$0: Unknown numeric month value>&2; exit 1#defaultesac#return 0假设通过传三个参数到脚本一month day year实现代码#!/bin/bashif $# -ne 3 ; then#若参数个数不为3,贝!|有误echo ''Usage: $0 month day yearex

32、it 1fi#判断参数1是数字还是单词,方法替换串中所有数字,若结果为空,则为数字,否则为 单词。if -n $(echo $1 | sed 's/:digit: /g ) # -n 检测串是为空thenmonthnoToName $1# 数字else#取第一个字母并将其变为大写,再将结果与取出的第二三字母组合month=,z$ (echo $1 | cut -cl | tr 1 : lower: ! 1 : upper : 1v month=,z$month$ (echo $1 I cut -c2-3 | tr 1 : upper : 1 ': lower: 1),z fie

33、cho Smonth $2 $3exit 0#输岀结果注:1 外国可以使用函数中定义的变琏,如函数monthnoToName中定义的month变量, 最后echo会用到它。2.多管道(|)的使用3month变量的合并,SvarSvar4. tr SET1 SET2转换/删除/替换命令,将默认将SE*M替换为SET2 tr默认从标准输入读取,处理后写入标准输出。5cut -c2-3 file 取文件每行第2, 3字母。扩展:处理MM/DD/YYYY or MM-DD-YYYY的形式。在判断三个参数前执行命令 set - $ (echo $1 I sed r s/ /- / /g1)。set 的-

34、命令可以将其后的参数 赋予位置参数($1,$2,.)。set指令用法4 格式化输出大数字,使输出结果更容易让人知道该输出数字的数量级。默认用逗号分隔整数部分,用点号分隔整数与小数部分,当然用户也可以使用-d指 定整数的分隔符,用-1指定整数与小数部分的分隔符。算法:1232342142 423023 => 默认:1,232, 342,142.423023(1) 首先分开整数部分integer和小数部分decimals sed -d. -fl和sed -d. -f2分别取两部分。(2) 整数部分的处理:当作数字来处理$运算/运算1) 每次取整数低三位,长度小于3就补前缀0 (避免岀现漏0情

35、况,例如低三位 为003时,取后便为值3)2) 将此次得到的三位与上一次得到的三位用分隔符(如果没有指左就默认)组合 起来。3) 整数去掉低三位,继续操作1)。当此整数小于等于999就不再继续。当字串来处理:1) 每次取低三位,cut -c $ ( ($#str - 2) ) -$#str)$#str为str的长度,必须为大括号。$()的部为str长度-2,代表倒数低三个字符。因为部是减法,所有此 为双小括号。2) 原串每次都要裁掉尾部三个字符,每次取到的字串的长度为循环判断条件。函数nicenumber ()作如上处理nicenumber ()# 传入 integer .decimal &q

36、uot;口 2000023 2, 32232332等#分别取整数部分和小数部分integer=$ (echo $1 | cut -d. -fl)decimal=$(echo $1 ! cut 一d 一f2)#判断小数部分是否存在,因为这涉及连接整数和小数的连接符问题#设。0为整数和小数之间分隔符,默认为.if -n decimal ; then#若非空,即有小数部分。#以 F四句可用一句表示:result=z/$DD: =,z.,z$remainder$result,z if -z $DD ; then#判断用户是否自建义整数与分隔符,若空#在小数部分前加分result=$DD$decimal

37、 隔符。fithousand=$integer while thousand -gt 999 doremainder=$(thousand%!000)while $#remainder -It 3 ;do#$#remainder为remainder串的长度remainder=0$remainder# 避免 remainder为OOx时的丢0情况。donethousand=$($thousand/1000)#以 F四句可用一句表示:result=z/$TD:$remainder$resultz,#上面蓝色部分表:若TD非空则返回TD,否则将,赋给TD.if -z $TD ; then#判断用户是

38、否自泄义整数分隔符,若空TD=,firesult=,z$TD$remainder$result,z# 与分隔符合成串。注意顺序doneif -n $thousand ; then# 若 非空result=,zSthousand$resultz,elif $resulresult #? =、'$TD ; t henresult=,z$ result#? “fiecho result脚本标志参数处理命令:getoptsvar带两个参数,第一个参数为带解析的参数标志序列串(如-f,-c等),以冒号(:) 分隔各标志,且以冒号:结朿第二个参数为:变量,每执行一次存放参数标志序列串中的一个标志字

39、符返回值:未解析结朿返回0,解析结束返回1涉及的左变量:SOPTARG每次解析标志对应的参数值便默认存放在此变量。5OPTIND当各标志处理无误情况下,该数值指示当前用到的最大位置参数($#)。此值使用容易出错(若参数的判断不完善时),还不如用 $#另外 $1, $2, $3, $4,=> 此时 $# 等于 4,当执行shift 1时,各个位置参数的值向一次向左右1次,此时$1的值为原 $2的值当执行shift 2时,各个位置参数的值向一次向左右2次,此时$1的值为原 $3的值。完整代码 nicenumber. sh nicenumber()#函数实现部分#处理脚本标志参数while g

40、etoptsoptdocase $opt in# $opt 为具体的标志字符d ) DD=Z,$OPTARG,Z ; ;# $OPTARG为标志抬总的参数值t ) TD=$OPTARG ;* ) echo 、'no arg-flag: $opt" >&2 ; exit 1esacdone#当脚本接收如此多的参数时,$1将不代表脚本最终要处理的大数字,所以做如下操 作。shift $ ( ($OPTIND - 1)nicenumber $1exit 0扩展:1.不同国家整数与小数的分隔符不同,使脚本能够处理各种整数与小数各种分隔符情 况。在传给脚本参数时需指定标志

41、-d程序中仅需在分隔整数与小数部分略修改为integer=$ (echo $1 | cut、'-d$ DD:-fl )decimal=$ (echo $1 I cut ''-d$DD -f2 )2 .另外,可以在程序执行之前分别初始化DD, TD默认值。3.检测传给脚本的大数值中是否含有非法的整小数分隔符,即存在与用户指左或默 认分隔符不同的符号。方法:删除其中所有数字,看剩下的容,若不空且不等于$DD,则非法 separator=z,$ (echo $1 | sed 's / : digit: / /gz ),z if -n separator &&a

42、mp; xySseparator" ! =、'$DD" ; then # 蓝色部 分可用-a表示exit 15. 检测输入整数的合法性,可负数(-1, -2均合法),可以指泄传入整数帀,不在 围则报错。参数:1或3个,当3个时,后两个为围。合法性:正负数的判断,围的判断。validint ()integer=$lmin=$2 max=$3#判断传参的合法性,以下判断是错误的,因为不管参数是否为空,实际上都传了 三个参数。1 S# -og 0#改成判断$1的容是否为空,就可 以了ocho ''you couldn't do#判断是否为负数,第一

43、个字符是否为-,如是,则判断后而的是否为整数。若 非负,则判断是否为整数if (echo $1 | cut -cl)z, = '、- ; thensignedinteger=,z$ integer#2"fi#如果就是一个符号-,则也是非法的if -z ''$integer,z ; thenecho ''Invalid input, just a ''一 is not allowed">&2#注意:&2三个字符紧连。return 1fi#如果非纯数字构成,则非法。if -n x'$ (echo integer | sed 's / : digit: / /gz ),z ; then echo 'Invalid integer, it includes some char but digit">&2 return 1fiintegez="$signedSinteger"#用判断,注意当min和max为空时(即未传围),我设定其为integer, 如此判断就不会出错。if Sinteger -It $min:=$ingeger ;thenecho、'$integer is too

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论