鉴于这周的主要内容是脚本,所以就来几道习题吧。
(额...由于刚换的新平台,使用还不太顺手,图片暂时插不了,请谅解。。。)
1.编写一个脚本,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;并生成8位随机口令并存在一个文件中,初步提示改口令,显示添加的用户的id号等信息。
#!/bin/bash
> random.txt①
read -p② "Please input a username: " username
id $username &> /dev/null③
if [ $? = 0 ]④;then
echo "user '$username' already exists"
else
useradd $username &&⑤ echo "$username already created successfully." && echo "`cat /dev/urandom⑥ | tr -dc 'A-Za-z0-9' |head -c 8`" >> random.txt
read -p "Please input your passwd: " passwd
echo "$passwd" |passwd --stdin $username⑦
echo "id信息:`id $username`"
fi
注释:
①表示每次执行程序时,生成的随机口令只保存最新的一个,不会追加,避免脚本被多次执行后混淆。
②read -p: 交互式提示输入信息
③&> /dev/null: 可以理解为把不想要显示在终端上的信息给屏蔽掉,相当于丢入了垃圾箱
④$?:保存最近的命令状态【知道 echo $? 的作用么?如果返回值为0,代表上条命令执行成功;返回值为非0,则代表失败。】这里用来判断上面的id $username 命令是否执行成功。
⑤&&:这个就不用多说了吧,表示前一条命令如果为真,执行后一条命令;前一条命令如果为假,执行结束,后一条就不看了
⑥/dev/null是个字符特殊文件,可以用来生成随机口令,但是需要经过处理。
⑦passwd -- stdin:从标准输入接收用户密码,只输入一次密码就可以。
【注:如果你执行了这个脚本,那么你就会发现一个小bug。密码输入时竟然是明文显示的,是不是有点太过高调?知道怎么能让它不显示么?有谁知道么?知道么?嘿嘿,其实很简单,-s选项有印象么,只需加上s就OK了。read -sp "Please input your passwd: " passwd这样密码就不会显示咯。还有一个命令也可以起到相同的作用,stty -echo:设置输入字符不回显,想显示用stty echo取消不回显状态就可以了】
2.编写一个脚本,提示用户输入yes or no(不区分大小写),并判断用户输入的是yes还是no或是其它信息。
#!/bin/bash
read -p "Yue ma? Please input your answer:" ans
case $ans in
[Yy][Ee][Ss] | [Yy])
echo "春风十里不如你!"
;;
[Nn][Oo] | [Nn])
ehco "从哪里来回哪里去!"
*)
echo "思想有多远你就滚多远!"
esac
【注:我这意思表达的够形象吧
这个脚本较简单,不需要多解释什么吧?" | "表示或的意思," [ ] "表示匹配里面的任意单个字符。还有注意开头和结尾的对应(case和esac),不然脚本执行不成功。】
3.编写脚本,提示输入一个目录,判断这个目录下所有文件的类型
read -p "Please input a dir: " dir
cd $dir
var=$(ls -a $dir)
for i in $(echo $var);do
file $i
done
cd - &> /dev/null
unset i var dir
【注:这里用了for循环,"ls -a"用来列出所有文件;"file"用来判断文件类型;"cd -"用来返回上一条命令;因为定义了变量,所以最后用unset释放掉变量。当然判断文件类型不是只有"file"这个命令,也可以用下面的方式判断
[ -h 文件名 ]:判断文件是否为链接文件
[ -d 文件名 ]:判断文件是否为目录文件
[ -f 文件名 ]:判断文件是否为普通文件
[ -b 文件名 ]:判断文件是否为块设备文件
[ -c 文件名 ]:判断文件是否为字符设备文件】
4.打印九九乘法表
①#!/bin/bash
for i in `seq 1 9`;do
for j in `seq 1 $i`;do
echo -en "${i}x$j=$[i*j]\t "
done
echo
done
②#!/bin/bash
export i=1;j=1
while [ $i -lt 10 ];do
while [ $j -le $i ];do
let s=$i*$j
echo -ne "${j}*${i}=$s\t"
((j++))
done
j=1
echo
((i++))
unset i j