shell编程(2)
【shell 变量基本用法及常用符号使用】
1.将主提示符改为用户的主目录名
1 echo $PS1 = $HOME
2.将字符串 DOS file c:>\$student\*赋值给变量 x,并显示出来
要求:确保字符串中多个空格、$、*等完全原样显示
3.在 shell 命令终端输入likes=(cosmos galaxy moon); likes[6]=mars,然后使用 echo 分别显示以下表达式的值
1 likes=(cosmos galaxy moon) 2 likes[6]=mars
第一行:定义一个一维数组like,里面有三个元素 cosmos galaxy moon
第二行:给数组like的第7个元素赋值成 mars,此时数组like中的元素为 commos galaxy moon 空 空 空 mars
①${likes[*]}:显示数组like中所有非空元素
②${likes[@]}:显示数组like中所有非空元素
③${#likes[*]}:显示数组like中非空元素的个数
④${#likes[@]}:显示数组like中元素的个数
⑤${#likes}:显示数组like中下标为0的元素(第一个元素cosmos)的长度(省略了下标[0]的表示,效果与⑥相同)
⑥${#likes[0]}:显示数组like中下标为0的元素(第一个元素cosmos)的长度
4.在 shell 命令终端输入 name=Phoenix,然后使用 echo 显示${name:-hello},观察结果;然后输入命令 unset name,再输入echo ${name:-hello}观察结果
变量name的值为Phonenix,不为空,所以${name:-hello}的值就是name的值,即Phonenix
unset用于删除已定义的变量,删除后name值为空,此时${name:-hello}的值为hello
5.在 shell 命令终端输入 name='/usr/share/doc/apg/php.tar.gz',然后使用 echo 分别显示${name%%.*}和${name%.*}的值,观察结果
修改 name 的值,让 name='/etc/apt/sources.list.d',再次使用 echo 分别显示${name%%.*}和${name%.*}的值,观察结果
%或%%后面的内容与name的值的末尾匹配,name的值去掉匹配到的结果就是表达式的值。
%表示最少匹配,%%表示最多匹配。
原理同上。
6.在 shell 命令终端输入 name=/usr/bin/X11,然后使用 echo 分别显示${name#*/}和${name##*/}的值,观察结果
修改 name 的值,让 name='/etc/apt/sources.list.d',再次使用 echo 分别显示${name#*/}和${name##*/}的值,观察结果
#或##后面的内容与name的值的开头匹配,name的值去掉匹配到的结果就是表达式的值。
#表示最少匹配,##表示最多匹配。
7.已知某同学提交的博客文章页面地址 address 如下:address='http://www.cnblogs.com/xyz/p/8569001.html',通过字符串匹配,如何得到其博客主页地址:homepage='http://www.cnblogs.com/xyz'。出由变量 address 得到变量 homepage 的 shell 命令实现。
1 #!/bin/bash 2 address="'http://www.cnblogs.com/xyz/p/8569001.html'" 3 homepage="homepage=""${address%/p*}""'" 4 echo $homepage
执行结果:
【shell脚本分析】
1.使用 vim/gedit 编写 shell 脚本文件 ex1.sh,其内容如下:
1 #!/bin/bash 2 # p145 4.8 3 4 count=$# 5 cmd=echo 6 while [ $count -gt 0 ] 7 do 8 cmd="$cmd \$$count" 9 count=`expr $count - 1` 10 done 11 eval $cmd
在 shell 命令终端分 3 次运行该脚本,运行结果如下:
在脚本ex1.sh中,$#是特殊Shell变量,指的是参数的个数。
执行. ex1.sh时,没有带参数,即参数个数为0,不符合while语句中的条件,什么都不执行也不输出。
执行. ex1.sh best wishes时,有两个参数,$count=2,满足while语句的条件:$count大于等于0,cmd的值为echo $2,count值减1,依旧满足while的条件,cmd的值为echo $2 $1,count值减1,不满足while的条件,退出循环,最后eval意思是运行cmd中的命令。
执行.ex1.sh god bless u时,有三个参数,原理同上,最后cmd的值为echo $3 $2 $1,再运行cmd中的命令。
整个脚本的作用是将参数倒序输出。参数有几个,while就循环几次。
运行. ex1.sh god bless u时,while第一次被执行时,第8行执行后cmd的值为echo $3。
2.使用 vim/gedit 编写 shell 脚本文件 ex2.sh,其内容如下:
1 #!/bin/bash 2 # p145 4.10 3 4 IS_USER_FOUND=0 5 date +%F 6 if who | grep "^$1"; then 7 IS_USER_FOUND=1; 8 write $1 <<Limitstring 9 hello 10 Limitstring 11 fi 12 13 if [ $IS_USER_FOUND -eq 0 ]; then 14 echo "user $1 is not found." 15 fi
在命令终端输入. ex2.sh cyj,结果如下:
line6 中,who | grep “^$1”用于判断用户名cyj是否在当前系统中。
line8~10是将第一个参数(cyj)重定向到LimitString中,向其发送Hello cyj。
3.使用 vim/gedit 编写 shell 脚本文件 ex3.sh,其内容如下:
1 #!/bin/bash 2 3 suffix=BACKUP--`date +%Y%m%d-%H%M` 4 5 for script in *.sh; do 6 newname="$script.$suffix" 7 echo "Copying $script to $newname..." 8 cp $script $newname 9 done
在命令终端输入. ex3.sh,结果如下:
该脚本功能是将当前文件夹下的所有.sh格式的文件都复制一份,新文件名为为原文件名加上后缀".BACKUP--当前时间"。
4.使用 vim/gedit 编写 shell 脚本文件 ex4.sh,其内容如下:
1 !/bin/bash 2 # realize function same as Command cat -n 3 4 function NL() { 5 while read x 6 do 7 (( ++line )) 8 echo "$line $x" 9 done 10 } 11 12 13 line=0 14 if [ $# -eq 0 ]; then 15 NL 16 else 17 while [ "$1" ] && [ -f "$1" ] 18 do 19 NL < $1 20 shift 21 done 22 fi
在 shell 命令终端分 3 次运行该脚本,运行结果如下:
执行. ex4.sh时,因为参数为空,所以脚本一直等待参数输入,输入后加上行号一起输出。
执行. ex4.sh /etc/apt/sources.list时,将etc/apt/sources.list中的内容作为参数,加上行号一起输出。
执行. ex4.sh /etc/apt/sources.list ex4.sh时,将/etc/apt/sources.list和ex4.sh中的内容作为参数,加上行号一起输出,先输出/etc/apt/sources.list中的,再输出ex4.sh中的。
line4-10 中函数 NL的作用是将用户输入的值保存在变量x中,然后输出行号和x的值。
line14 中,条件测试满足时,脚本执行函数NL的功能。
line17-line21,从屏幕获取输入,读入到NL中,shift 命令将参数左移一位,最左边的参数丢弃。
【shell脚本编写】
1.编写一个shell脚本,它把第二个位置参数以及其后的各个参数指定的文件复制到第一个位置参数指定的目录中。
1 #!/bin/bash 2 dir=$1 3 shift 4 for script in $@ 5 do 6 cp $script $dir 7 done
2.打印给定目录下的某些文件,由第一个参数指出文件所在的目录,其余参数是要打印的文件名。
1 #!/bin/bash 2 cd $1 3 shift 4 for file in $@ 5 do 6 cat $file 7 done
3.利用for循环将当前目录下的.c文件移到指定的目录下,并按文件大小排序,显示移动后指定目录的内容。
1 #!/bin/bash 2 echo "要移入的目录:" 3 read x 4 for script in *.c;do 5 echo "Moving $script to $x..." 6 mv $script $x 7 done 8 cd $x 9 ls -Sl
4.设计一个程序cuts,它由标准输入读取数据,获取由第一个参数n和第二个参数m所限定范围的数据,n和m都是整数,即从输入的字符串中抽取第n个字符至第m个字符之间的所有字符(包括这两个字符)。例如:
$cuts 11 14
this is a test of cuts program (输入)
test (结果)
1 #!/bin/bash 2 read str 3 echo $str | cut -c $1-$2
5.猜数字游戏,具体要求如下:
①写一个函数random_100生成0~100之间的随机数
②用户从键盘输入竞猜数字,如果猜错了,提示用户所猜数字偏大或偏小,用户继续猜,直到猜对为止。
1 #!/bin/bash 2 echo "Please input the num(1-100) " 3 read num 4 5 random_100 () { 6 s=$((RANDOM % 100)) 7 } 8 random_100 9 while [[ "$num" != $s ]] 10 do 11 if [ "$num" -lt $s ] 12 then 13 echo "Too small. Try again!" 14 read num 15 elif [ "$num" -gt $s ] 16 then 17 echo "To high. Try again" 18 read num 19 else 20 exit 0 21 fi 22 done 23 24 echo "Congratulation, you are right! "