脚本练习20170704
1 . 编写脚本,求100以内所有正奇数之和
vim positive_old.sh
#!/bin/bash
sum=0
for i in {1..100};do
let sum+=$i
done
echo $sum
2 . 编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态,并统计在线和离线主机各多少
#!/bin/bash
net='172.17.253'
uphost=0
downhost=0
for i in {1..20};do
ping -c 1 -v 1 ${net}.$i &> /dev/null
if [ $? -eq 0 ];then
echo "${net}.$i is up"
let uphost++
else
echo "${net}.$i is down"
let downhost++
fi
done
echo "Up host:$uphost"
echo "Down host:$downhost"
3 . 编写脚本,打印九九乘法表
4 . 编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大值和最小值
cat max_min.sh
#!/bin/bash
#
declare -a rand
for ((i=0;i<10;i++));do
rand[$i]=$RANDOM
[ $i -eq 0 ] && min=${rand[0]} && max=${rand[0]} && continue
[ "$min" -gt "${rand[$i]}" ] && min=${rand[$i]}
[ "$max" -lt "${rand[$i]}" ] && max=${rand[$i]}
done
echo "all random is ${rand[*]}"
echo "max is $max"
echo "min is $min"
5 . 编写脚本,实现打印国际象棋棋盘
#!/bin/bash
red(){ echo -e '\033[41m \033[0m';}
yellow(){ echo -e '\033[43m \033[0m';}
a=1
while [ $a -le 10 ]
do
b=1
while [ $b -le 10 ]
do
let c=$a+$b
if [ `expr $c % 2` = "0" ]
then
echo -en `red``red``red`
else
echo -en `yellow``yellow``yellow`
fi
let b++
done
let a++
echo
done
6 . 后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机执行命令:echo $RANDOM|md5sum|cut –c1-10
后的结果,请破解这些字符串对应的RANDOM值
#!/bin/bash
read -p "please enter MD5 encrypts the random number " num
for j in `seq 0 32767`;
do
k=`echo "$j" |md5sum|cut -c1-10`
if [[ $num == $k ]];then
echo "$j"
exit
fi
done
echo $j
7 . 每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并退出脚本
read -p "Enter a user name: " username
while true;do
if who | grep "^$username" &> /dev/null;then
break
fi
sleep 3
done
echo "$username logged on" >> /tmp/user.log
8 . 随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出
vim number.sh
#!/bin/bash
read -p "Please input number: " num
if [ $num -ge `echo $[$RANDOM%10]` ] ; then
echo "input number is big"
elif [ $num -le `echo $[$RANDOM%10]` ] ;then
echo "input number is little"
else
echo "equal"
fi
9 . 用文件名做为参数,统计所有参数文件的总行数
10 . 用二个以上的数字为参数,显示其中的最大值和最小值
11 . 扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功。
12 . 编写服务脚本/root/bin/testsrv.sh,完成如下要求
(1) 脚本可接受参数:start, stop, restart, status
(2) 如果参数非此四者之一,提示使用格式后报错退出
(3) 如是start:则创建/var/lock/subsys/SCRIPT_NAME, 并显示“启动成功”
考虑:如果事先已经启动过一次,该如何处理?
(4) 如是stop:则删除/var/lock/subsys/SCRIPT_NAME, 并显示“停止完成”
考虑:如果事先已然停止过了,该如何处理?
(5) 如是restart,则先stop, 再start
考虑:如果本来没有start,如何处理?
(6) 如是status,则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAMEis running...”如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is stopped...”其中:SCRIPT_NAME为当前脚本名
(7) 在所有模式下禁止启动该服务,可用chkconfig和service命令管理
cat testsrv.sh
#!/bin/bash
#
# chkconfig:- 88 12
# description: test service script
#
prog=$(basename $0)
lockfile=/var/lock/subsys/$prog
start() {
if [ -e $lockfile ]; then
echo "$prog is aleady running"
return 0
else
touch $lockfile
[ $? -eq 0 ] && echo "Starting $prog finished"
fi
}
stop() {
if [ -e $lockfile ];then
rm -f $lockfile && echo "stop $prog ok"
else
echo
echo "$prog is stopped yet"
fi
}
status() {
if [ -e $lockfile ];then
echo "$prog is running"
else
echo "$prog is stopped"
fi
}
usage() {
echo "Usage:$prog {start|stop|restart|status}"
}
if [ $# -lt 1 ];then
usage
exit 1
fi
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
usage
esac
[root@danran init.d]# mv testsrv.sh /etc/init.d/testsrv
[root@danran init.d]# chkconfig --add testsrv
[root@danran init.d]# chkconfig --list | grep testsrv
testsrv 0:off 1:off 2:off 3:off 4:off 5:off 6:off
13 . 编写脚本/root/bin/copycmd.sh
(1) 提示用户输入一个可执行命令名称
(2) 获取此命令所依赖到的所有库文件列表
(3) 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下;
如:/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd
(4) 复制此命令依赖到的所有库文件至目标目录下的对应路径下:
如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
(5)每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit退出
cat cmdcp.sh
#!bin/bash
#ch_root="/app/sysroot"
[ ! -d $ch_root ] && mkdir $ch_root
bincopy() {
if which $1 &> /dev/null;then
local cmd_path=`which --skip-alias $1`
local bin_dir=`dirname $cmd_path`
[ -d ${ch_root}${bin_dir} ] || mkdir -p ${ch_root}${bin_dir}
[ -f ${ch_root}${cmd_path} ] || \cp -f $cmd_path ${ch_root}${bin_dir}
return 0
else
echo "Command not found"
fi
}
libcopy() {
local lib_list=$(ldd `which --skip-alias $1` | grep -Eo '/[^[:space:]]+')
for loop in $lib_list;do
local lib_dir=`dirname $loop`
[ -d ${cn_root}${lib_dir} ] || mkdir -p ${ch_root}${lib_dir}
[ -f ${ch_root}${loop} ] || cp $loop ${ch_root}${lib_dir}
done
}
read -p "Please input copy path: " path
ch_root=$path
read -p "Please input a command or quit: " command
while [ "$command" != "quit" ];do
if bincopy $command;then
libcopy $command
fi
read -p "Please input a command or quit: " command
done
14 . 编写函数实现两个数字做为参数,返回最大值
15 . 编写函数实现数字的加减乘除运算,例如输入1 + 2,,将得出正确结果
16 . 斐波那契数列又称黄金分割数列,因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2)
利用函数,求n阶斐波那契数列
#!/bin/bash
#
fab () {
if [ $1 -eq 1 ];then
echo 1
elif [ $1 -eq 2 ];then
echo 1
else
echo $[$(fab $[$1-1])+$(fab $[$1-2])]
fi
}
fab 7
17 . 汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘
利用函数,实现N片盘的汉诺塔的移动步骤
[root@danran scripts]# cat hnt.sh
#!/bin/bash
tep=0
move (){
let step++
echo "$step: move plate $1 $2 -----> $3"
}
hanoi(){
if [ $1 -eq 1 ];then
move $1 $2 $4
else
hanoi "$[$1-1]" $2 $4 $3
move $1 $2 $4
hanoi "$[$1-1]" $3 $2 $4
#这三行是经典所在,将问题简化成三次move,其中第一次和第三次都是用hanoi函数实现功能,第二步是将最底下盘移到目标位置
fi
}
read -p "please input the number of plates: " number
hanoi $number A B C
18 . 编写脚本,定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;要统计其下标为偶数的文件中的行数之和
vim loglines.sh
#!/bin/bash
#
declare -a filename
filename=(/var/log/.log)
filenum=${#filename[]}
sum=0
echo "file numbers is $filenum"
for i in `seq 0 2 $[filenum-1]`;do
let fileline=`cat ${filename[$i]}|wc -l`
let sum=$fileline+$sum
done
echo sum is $sum
unset filenum filename
vim loglines.sh
#!/bin/bash
#
declare -a filename
filename=(/var/log/*.log)
filenum=${#filename[*]}
sum=0
echo "file numbers is $filenum"
for i in `seq 0 $[filenum-1]`;do
if [ $[$i%2] -eq 0 ];then
let fileline=`wc -l ${filename[i]} | cut -d' ' -f 1`
let sum=$fileline+$sum
done
echo sumlines is $sum
unset filenum filename
19 . 每隔3秒钟到系统上获取已经登录的用户的信息:如果docker登录了,则记录于日志中,并退出
read -p "Enter a user name: " username
while true;do
if who | grep "^$username" &> /dev/null;then
break
fi
sleep 3
done
echo "$username logged on" >> /tmp/user.log
法二
#!/bin/bash
#
read -p "Enter a user name: " username
until who | grep "^$username" &> /dev/null;do
sleep 3
done
echo "$username logged on" >> /tmp/user.log
20 . 将下图所示,实现转置矩阵matrix.sh
1 2 3 ===> 1 4 7
4 5 6 ===> 2 5 8
7 8 9 ===> 3 6 9
vim matrix.sh
#!/bin/bash
arr=([00]=1 [01]=2 [02]=3 [10]=4 [11]=5 [12]=6 [20]=7 [21]=8 [22]=9)
size=3
showmatrix () {
for ((i=0;i<size;i++));do
for ((j=0;j<size;j++));do
echo -e "${arr[$i$j]} \c"
done
echo
done
}
echo "Before convert"
showmatrix
for ((i=0;i<size;i++));do
for ((j=i;j<size;j++));do
if [ $i -ne $j ];then
temp=${arr[$i$j]}
arr[$i$j]=${arr[$j$i]}
arr[$j$i]=$temp
fi
done
done
echo "After convert"
showmatrix
21 . 输入若干个数值存入数组中,采用冒泡算法进行升序或降序排序
#!/bin/bash
declare -a rand
declare -i sub=echo "Please input the numbers you want to sort:"
read -a rand
for ((i=0;i<${#rand[*]}-1;i++));do
for ((j=0;j<${#rand[*]}-i-1;j++));do
if [ ${rand[$j]} -gt ${rand[$j+1]} ];then
sub=${rand[$j+1]}
rand[$j+1]=${rand[$j]}
rand[$j]=$sub
fi
done
done
echo "The numbers have been sorted:${rand[*]}"