一、实验内容
四块:1、shell变量基本用法及常规符号使用。2、shell中脚本分析。3、shell脚本编写。4、修改配置文件定制个性化操作系统或编写设立了实现任务的自动化处理。
二、实验步骤
1、shell变量基本用法及常规符号使用
(1)将主提示符改为用户的主目录名
(2)将字符串DOS file c:>\$student\*赋值给变量x,并显示出来
关于多个空格,一开始用 echo $x 结果总是只显示一个空格,上网查阅后得知,应该写成 echo "$x",这与shell解析规则有关。
shell的解析过程:
- 替换变量
- 执行命令
- 按IFS划分命令之后的参数,用""和''包围的部分作为命令的一个参数。
echo $tmp的执行过程为:
- 替换变量:echo a b d
- 执行命令:echo a b d
- 按IFS划分echo命令之后的参数a, b, d
所以打印出来就是a b d,多个空格只显示了一个。
关于这个IFS,它是一个set型环境变量,如下是一些值得注意的地方。
1. IFS的默认值为:空白(包括:空格,tab, 和新行),将其ASSII码用十六进制打印出来就是:20 09 0a (见下面的shell脚本)。
2. IFS对空格的空白的处理和其他字符不一样,左右两边的纯空白会被忽略,多个连续的空白被当成一个IFS处理。
(3)在shell命令终端输入 likes=(cosmos galaxy moon);likes[6]=mars,然后使用echo分别显示一下表达式
① ${ likes[*]}
显示likes数组的所有非空元素,作为一个字符串返回
② ${ likes[@]}
显示likes数组的所有非空元素,每一个数组元素作为一个独立的字符串
③ ${# likes[*]} ④ ${# likes[@]} ⑤ ${# likes}
都是显示数组likes中已经设置好的元素的个数
⑥ ${# likes[0]}
显示likes数组的第一个元素的长度,likes[0]为 cosmos,长度为6
(4)在shell命令终端输入name=Phoenix,然后使用echo显示表达式①,观察结果;然后输入命令 unset name,在输入表达式①观察结果。结合两次结果写出表达式作用。
① ${name:-hello}
作用:如果name不为空,引用的就是name这个变量的内容,如果为空则输出-后面的字符串的内容
(5)在 shellshell shell命令终端输入name= '/usr/share/doc/apg/php.tar.gz ',然后使用 echo分别显示表达式①和②的值 观察结果。 观察结果。
修改 name的值值,让 name='/etc/apt/sources.list.d',再次使用echo分别显示表达式①和②的值,观察结果写出表达式的作用 。
① ${name%%.*} ②${name%.*}
命令①②中均有 .*,此时pattern可以匹配掉 .后面的任意字符,一个%表示去掉最少匹配的部分,所以都显示了一个后缀,分别是.tar,.list。两个%表示去掉做多匹配的部分,做多匹配即去掉全部后缀,所以均只显示了文件名。
(6)在shell命令终端输入name=/usr/bin/X11,然后使用echo分别显示表达式①和②的值,观察结果。
修改name的值,让name='/etc/apt/sources.list.d',再次使用echo分别显示表达式①和②的值,观察结果。
结合结果,写出表达式的作用。
①${name#*/}②${name##*/}
(提示:参考教材4.6.3节)
${name#*/}中pattern为*/,即匹配任意字符加上/。#表示去掉最少匹配部分,##表示去掉做多部分,所以,第一个name值中只去掉了/,当使用##时,可以去掉X11之前包含/的全部字符。第2个name也是如此
(7)已知某同学提交的博客文章页面地址address如下:
address='http://www.cnblogs.com/xyz/p/8569001.html'
通过字符串匹配,如何得到其博客主页地址:
homepage='http://www.cnblogs.com/xyz'
写出由变量address得到变量homepage的shell命令实现。
(提示:参考前序练习(5))
2、shell中脚本分析
(1)使用vim/gedit编写shell脚本文件ex1.sh,其内容如下:
# !/bin/bash
count=$#
cmd=echo
while [ $count -gt 0 ]
do
cmd="$cmd \$$count"
count=`expr $count -1`
done
eval $cmd
以如下方式运行脚本:
①第1次运行:. ex1.sh
②第2次运行:. ex1.sh best wishes
③第3次运行:. ex1.sh god bless u
①整个shell脚本的功能是什么?
整个脚本的功能是将参数倒序输出。
②第8行、第9行、第11行的功能是什么?
第8行指将输入参数个数给cmd,第9行指每循环一次,$count数减少1,第11行指运行cmd命令
③每次运行时,脚本中的while循环分别执行几次?
运行次数等于参数
④运行. ex1.sh god bless u时,while循环体第1次被执行时,第8行执行后变量cmd的值为?
值为3
(2)使用vim/gedit编写shell脚本文件ex2.sh,其内容如下:(教材P145 4.10)
# !/bin/bash
IS_USER_FOUND=0
date +%F
if who |grep "^$1";then
IS_USER_FOUND=1;
write $1 <
Limitstring
fi
if [ $IS_USER_FOUND -eq 0 ]; then
echo "user $1 is not found."
fi
在命令终端输入. ex2.sh jsj,(实际执行时,请将jsj替换为您电脑中的登录用户名)结合结果及帮助信息,回答下列问题。
①line6中,who | grep “^$1”的功能?
who表示查看当前登录系统的用户,grep "^$1" 表示检索参数列表第一个参数的值,命令中为 kyo,所以 结果中显示为kyo
②line8~10功能?
line8~10是将第一个参数重定向到LimitString中,向其发送hello kyo。
(3)使用vim/gedit编写shell脚本文件ex3.sh,其内容如下:
# !/bin/bash
suffix=BACKUP--`date +%Y%m%d-%H%M`
for script in *.sh; do
newname="$script.$suffix"
echo "Copying $script to $newname..."
cp $script $newname
done
在命令终端输入. ex3.sh,结合结果及帮助信息,回答下列问题。
①截图显示运行结果。
②该脚本的功能是?
将所有的.sh文件备份。新的备份文件名字为原来的文件名+日期+时刻
(4)使用vim/gedit编写shell脚本文件ex4.sh,其内容如下:
# !/bin/bash
function NL(){
while read x
do
(( ++line))
echo "$line $x"
done
}
line=0
if [ $# -eq 0 ];then
NL
else
while [ "$1" ] && [ -f "$1" ]
do
NL<$1
shift
done
fi
在shell命令终端分3次运行该脚本,观察其运行结果。
①第1次运行:. ex4.sh
②第2次运行:. ex4.sh /etc/apt/sources.list
③第3次运行:. ex4.sh /etc/apt/sources.list ex4.sh
结合运行结果,分析shell脚本功能。回答:
①line4-10中函数NL的功能?
按行读取参数中给定的文件,每行前面加上行号。
②line14中,条件测试满足时,脚本执行的功能是?
条件测试满足时,脚本执行函数NL的功能。
③line17-line21,这部分脚本的功能是?
如果传入的文件参数名不为false并且该文件是常规文件,则调用NL方法读取该文件。读完之后参数位置左移,进行while中的判断,若为true,则用NL继续读取第二个参数表示的文件。
3. shell脚本编写
此部分要求贴出实现相应要求的shell脚本程序,并截图显示脚本执行及结果
(1)第4章思考题4.9
# !/bin/bash
dir=$1
shift
while [ $# -ne 0 ] && [ -f "$#" ]
do
cp $1 $dir
shift
done
(2)第4章思考题4.11
dir=$1
shift
while [ "$1" ] && [ -f "$1" ]
do
file=$1
cat -n $1
shift
done
(3)第4章思考题4.12
# !/bin/bash
dir=$1
for file in *.c
do
mv $file $dir
done
ls $dir
~
(4)第4章思考题4.18
# !/bin/bash
read x
echo $x | cut -c $1-$2 $x
(提示:利用cut命令及相应选项,考虑位置参数使用)
无论如何都是报错,这个字符范围怎么就不对了???
(5)猜数字游戏
# !/bin/bash
randomNumber=$((RANDOM%100))
echo "write any number in 1-100"
read x
while [ $x -ne $randomNumber ]
do
if [ $x -lt $randomNumber ]
then
echo "Opps,try it bolder"
else
echo "Opps,try it less"
fi
echo "try again"
read x
done
echo "gotcha!"
~
具体要求如下:
①写一个函数random0_100生成0~100之间的随机数
②用户从键盘输入竞猜数字,如果猜错了,提示用户所猜数字偏大或偏小,用户继续猜,直至猜对为止。
(提示:shell内部系统变量RANDOM生成0~32767之间的整数随机数)
小结:
这次试验学到了不少东西,很多东西还是自己动手做才行,四点做到七点半,lay了。