Linux 第30天: (08月5日) 练习和作业

时间:2023-02-13 09:50:05
变量脚本



1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小



server_ip=`ifconfig|grep'inet\b'|grep -v '127.0.0.1'|tr-s ' '|cut -d' ' -f3`
CPUmod=`lscpu|grep -i "model name:"`
Meminfo=`free -h|sed -n '2p'|tr -s ' '|cut -d' ' -f2`
DISKinfo=`fdisk -l |sed -n '2p'|sed -r 's/.*[[:space:]][0-9].*GB).*/\1/g`


echo 'hostname:' $(hostname)
echo 'hostIP:' ${server_ip}
echo 'OS version:' $(cat /etc/redhat-release)
echo 'Kernel version:' $(uname -r)
echo 'CPU:' $CPUmod
echo 'Memory:' $Meminfo
echo 'Harddisk:' $DISKinfo





2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中



backupdir="/root/etc$(date +%F)"
cp -a /etc $backupdir
echo "backup $backupdir finished."





3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值



maxused=`df -h|grep '/dev/sd' |tr -s ' '|sort -nr -t' ' -k5 |head -l |cut -d' ' -f5`
echo'硬盘分区利用率最大值为:'$maxused





4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序



netstat -nt |tr -s ' '|cut -d' ' -f5|tr -cs'0-9.' '\n'|egrep'([0-9]+.){3}[0-9]+'|sort |uniq -c|sort -nr|tr -s ' '

'\t'





1、编写脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和



dir=/etc/passwd
n=10
m=20
id_10=`cat $dir|head -$n|tail -1|cut -d: -f3`
id_20=`cat $dir|head -$m|tail -1|cut -d: -f3`
num=$[id_10+id_20]



====================================================



UID1=`sed -n '10p'/etc/passwd |cut -d: -f3`
UID2=`sed -n '20p'/etc/passwd |cut -d: -f3`
let Sumid=$UID1+$UID2





2、编写脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和



File1=`grep'^$' $1|wc -l`
File2=`grep'^$' $2|wc -l`
let Sumspace=$File1+$File2
echo "the sum of $1 + $2 spacelines is $Sumspace"
unset File1
unset File2
unset Sumspace





3、编写脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录*有多少个一级子目录和文件



File1=`ls -A /etc |wc -l`
File2=`ls -A /var |wc -l`
File3=`ls -A /usr |wc -l`
let Sumfile=$File1+$File2+$File3
echo "the sum is $Sumfile"
unset File1
unset File2
unset File3
unset Sumfile





文本测试脚本



1、编写脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数



[[$# -lt 1]] && echo "at least a parameter" ||(grep '^$' $1 |wc -l)





2、编写脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”



ping -c1 -w1 $1 &>/dev/null && [[$? -eq 0]] && echo "该IP地址可以访问"||echo "该IP地址不可以访问"





3、编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如果超过80%,就发广播警告空间将满



disk= `df |tr -s " "|cut -d" " -f5|cut -d% -f1|sort -n|tail -1`
inode=`df -i|tr -s " "|cut -d" " -f5|cut -d% -f1|sort -n|tail -1`
[[ $disk -ge 80 ]] && "echo "80%" | mail -s diskover80% root"
[[ $inode -ge 80 ]] && "echo "80%" | mail -s inodeover80% root"





判断主机名是否为空, 或等于指定主机名, 如果是, 则改名为



[ -z “$HOSTNAME” -o $HOSTNAME ==\"localhost.localdomain" ] && hostname www.magedu.com





判断文件是否普通文件和有执行权限, 如果是, 则输出文件内容



[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab





1、编写脚本/bin/per.sh,判断当前用户对指定的参数文件,是否不可读并且不可写



[! -r $1 -a ! -w $1 ] && echo "can't r can't w" || echo " can r can w"





2、编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件



[ -f $1 -a ${$1##*.} == "sh" ]&& chmod +x $1 && echo "have right"||echo "error"





3、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和允许普通用户登录系统



[ -e $1 ] && echo "you can login" || (rm -rf /home/`whoami`; echo "you can login")
[ -e $1 ] && (rm -rf /home/`whoami`; echo "you can not login")||echo "you can login"



===============================================================



[ -f /etc/nologin ] && (echo "普通用户已不能登录")|| (touch /etc/nologin)





写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,先判断是否合格IP,否,提示IP格式不合法并退出,是,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”



[[$# -lt 1]] && echo "需要一个IP地址作为参数" $$ exit
[["$1"=~(([0-9]|[0-9][1-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9][1-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$]]
[ $? -ne 0 ] && echo "IP地址不合法" && exit
ping -c1 -W1 $1 > /dev/null && echo "IP可以被正常访问" || echo "IP不能被正常访问"





计算1+2+3+...+100的值



echo `seq -s + 1 100 |bc`



==========================



echo $[`seq -s + 1 100`]





计算从脚本第一参数A开始,到第二个参数B的所有数字的总和,判断B是否大于A,否提示错误并退出,是则计算之



sumNtoN1.sh



[[ $# -lt 2 ]] && echo "至少需要两个不同的整数作为参数,第一个参数需要小于第二个参数" && exit
[[ $1 =~ \b[[:digit:]]+\b ]]
[ $? -ne 0 ] && echo "第一个参数必须为整数" && exit
[[ $2 =~ ^[[:digit:]]+$ ]]
[ $? -ne 0 ] && echo "第二个参数必须为整数" && exit
[[ $1 -eq $2 ]] && echo "两个整数不能相同" && exit
[[ $1 -ge $2 ]] && echo "第一个参数需要小于第二个参数" && exit
echo -n "$1到$2之间所有整数的和为"
echo `seq $1 $2 | tr '\n' '+' | sed -r 's@\+$@@g'`| bc



============================



echo `seq -s + $1 $2 |bc`





脚本判断年龄



checkage.sh


read -p "How old are you?" age
if [ $age -ge 0 -a $age -le 18 ];then
echo "hello,baby"
elif [ $age -gt 18 -a $age -le 60 ];then
echo "work hard"
elif [ $age -gt 60 -a $age -le 150 ];then
echo "happy day"
else
echo "welcome to the earth"
fi





根据命令的退出状态来执行命令



if ping -c1 -W2 station1 &> /dev/null; then
echo 'Station1 is UP'
elif grep "station1" ~/maintenance.txt &>/dev/null
then
echo'Station1isundergoingmaintenance'
else
echo'Station1isunexpectedlyDOWN!'
exit1
fi





条件脚本



1、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息



useradd $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "user $1 add"
id $1
else
echo "user exist already or no argument "
fi





2、编写脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息



yesorno2.sh



echo -n "Enter you choice yes|no:"
read Choice
Choice1=`echo $Choice | tr '[a-z]' '[A-Z]'`
case $Choice1 in
Y|YES)
echo "you select yes."
;;
N|NO)
echo "you select no."
;;
*)
echo "you select others."
;;
esac
#
unset Choice
unset Choice1



========================================



yesorno3.sh



read -p "please enter yes/no: " yesorno
case $yesorno in
[yY][Ee][Ss]|[Yy])
echo "Yes"
;;
[Nn][Oo]|[Nn])
echo "No"
;;
*)
echo "Other char"
;;
esac





3、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)



read -p "please enter file: " filename
if [ -L $filename ];then
echo "$filename is Symbol file."
elif [ -c $filename ];then
echo "$filename is char file."
elif [ -d $filename ];then
echo "$filename is dir file."
elif [ -b $filename ];then
echo "$filename is block file."
elif [ -f $filename ];then
echo "$filename is common file."
elif [ -p $filename ];then
echo "$filename is pipe file."
elif [ -S $filename ];then
echo "$filename is socket file."
else
echo "please enter a Correct file"
fi



===============================================



if [[ $# -lt 1 ]]
then
echo -e "Error: No argument.\n\tUsage: $0 FILENAME"
exit 1
else
if [[ -e $1 ]]
then
FileType=`ls -ld $1 | cut -c1`
case $FileType in
l)
echo "$1 is a link file"
;;
d)
echo "$1 is a diretory"
;;
-)
echo "$1 is a common file"
;;
*)
echo "$1 is other file"
;;
esac
else
echo "$1: no such file or diretory."
fi
fi
unset FileType





4、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数



read -p "please input a number: " number
[ -z "$number" ] && echo "you must input a number " && exit

if let var=$number &> /dev/null ; then
if [ "$?" -eq 0 ]; then
if [ "$number" -lt 0 ]; then
echo "$number is 负整数"
elif [ $number -eq 0 ]
echo " $number is 零"
else
echo "$number is 正整数"
fi
fi
else
echo "$number 不是一个整数"
fi



=================================================



read -p "请入一个数字: " num
[ -z "$num" ]&&echo "请输入一个数字"&&exit 1
NUM=$(echo $num |grep -Eo "\-?[[:digit:]]+")
if [ "$NUM" == "$num" ];then
if [ "$NUM" -lt "0" ];then
echo "您输入的是一个负整数"
elif [ "$NUM" -eq "0" ];then
echo "您输入的是一个0"
else
echo "您输入的是一个正整数"
fi
else
echo "您输入的不是一个整数 请重新运行脚本"
fi





循环脚本



for脚本



for2.sh



#!/bin/bash
for i in {1.3}
do
echo $i
for i in {1..10}
do
echo -e "$i\c"
done
echo $i
done





编写脚本删除大于1000的属组



delUserGt1000.sh



#!/bin/bash
#
for groupentry in `getent group | cut -d: -f1,3`;do
groupna=`echo $groupentry | cut -d: -f1`
groupidnum=`echo $groupentry | cut -d: -f2`
#echo -e "$groupna $groupidnum \n"
[[ $groupidnum -gt 1000 ]] && groupdel "$groupna"
done



==============================



groupdel.sh



GID=`getent group| cut -d: -f3`
for i in `$GID`
do
if [ $GID -gt 1000];then
GroupName=getent group|grep "$GID"|cut -d: -f1
groupdel $GroupName &>/dev/null
else
echo "the group is system group"
fi
done





1、判断/var/目录下所有文件的类型



模块化调用



for filename in /var/*; do echo $filename |filetype.sh; done



==============================================================



forfiletype.sh



if [[ $# -lt 1 ]]
then
echo -e "Error: No argument.\nUsage: $0 DIR"
exit 1
fi
#=============== plan 1 =================
# diretory judge
if [[ ! -d $1 ]]
then
echo "Error: $1 is not a diretory or No such file."
exit 2
fi
# /PATH | /PATH/ to /PATH
DirName=`echo $1 | sed -r 's@(.*)/$@\1@'`
for i in `ls -A $1`
do
FileType=`ls -dl $DirName/$i | cut -c1`
case $FileType in
d)
echo "$DirName/$i is a diretory."
;;
-)
echo "$DirName/$i is a common file."
;;
l)
echo "$DirName/$i is a link file."
;;
b)
echo "$DirName/$i is a block file."
;;
c)
echo "$DirName/$i is a character file."
;;
p)
echo "$DirName/$i is a pipe file."
;;
s)
echo "$DirName/$i is a socket file."
;;
*)
echo "$DirName/$i is unkwon file"
;;
esac
done
#================== plan 2 ==============
cd $1 &> /dev/null
# diretory judge
if [[ $? = 0 ]]
then
for i in `ls -A $1`
do
FileType=`ls -dl $DirName/$i | cut -c1`
case $FileType in
d)
echo "$i is a diretory."
;;
-)
echo "$i is a common file."
;;
l)
echo "$i is a link file."
;;
b)
echo "$i is a block file."
;;
c)
echo "$i is a character file."
;;
p)
echo "$i is a pipe file."
;;
s)
echo "$i is a socket file."
;;
*)
echo "$i is other file"
;;
esac
done
else
echo "$1 is not a diretory"
exit 2
fi
unset DirName
unset FileType





2、添加10个用户user1-user10,密码同用户名



foruserAD



if [[ $# -lt 1 ]]
then
echo -e "Error: No option \n\t-d\tdelete user1-user10\n\t-a\tadd user1-user10 "
exit 1
fi

for i in $(seq 10);do
case $1 in
-d|--del)
if id user$i &> /dev/null;then
userdel -r user$i
echo "user$i: Delete complete!"
else
echo "user$i: No such user!"
fi
;;
-a|--add)
if id user$i &> /dev/null;then
echo "user$i"| passwd --stdin "user$i" &> /dev/null
echo -e "user$i: Already existed!\nAnd authentication tokens updated successful!"
else
useradd user$i &> /dev/null
echo "user$i"| passwd --stdin "user$i" &> /dev/null
echo " user$i: Add complete!"
fi
;;
*)
echo "Error:"
echo -e "$0 : Unknow option!\nplease use '-a''--add' to add user or '-d''--dell'to delect user"
exit 1
;;
esac
done





3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;“K34filename stop”“S66filename start”



forrc3.sh



for i in `ls /etc/rc.d/rc3.d`
do
FileC1=`echo $i | cut -c1`
case $FileC1 in
K)
echo -e "$i\tstop"
;;
S)
echo -e "$i\tstart"
;;
*)
echo "unkown file"
;;
esac
done





4、编写脚本,提示输入正整数n的值,计算1+2+3+…n的总和



and.sh



#!/bin/bash

read -p 'please input the number' n
num=`echo $n|grep "^[[:digit:]]\+$"`
if echo $n|grep -q "^[[:digit:]]\+$" ;then

if [ $num -eq 0 ];then
echo "the number is 0"
exit
fi
else

echo "the number is negtive"
exit
fi
string=0
for i in `seq $n`;do
sum=$[$sum+$i]
string=$string+$i
done
echo "$string=$sum"


================================



read -p "please input n:" n
sum=0;for i in {1..n};
do
sum=$(($sum+1));
done;
echo $sum





5、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态



fortestIP.sh



echo -n "Enter IP:"
read IP
#get IP segment
Segment=`echo $IP | cut -d. -f1-3 `.
#
if echo $IP | egrep '\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>' &>/dev/null
then
#test host
for i in `seq 240 255`
do
if ping -c 1 -W 1 $Segment$i &> /dev/null
then
echo -e "$Segment$i\tonline"
else
echo -e "$Segment$i\toffline"
fi
done
else
echo "$IP is invalid"
fi





6、打印九九乘法表



for99tables.sh



for i in `seq 9`
do
for j in `seq 1 $i`
do
echo -ne "$i*$j=$(($i*$j))\t"
done
echo
done

echo "==================== plan 2 ===================="

for (( i=1 ; i<=9 ; i++ ))
do
for (( j=1 ; j<=i ; j++ ))
do
echo -ne "$i*$j=$(($i*$j))\t"
done
echo
done
unset i
unset j





while脚本



i=1;while [$i -le 9 ]; do echo $i; let i++;done





1、编写脚本,求100以内所有正整数之和



i=1
sum=0
while [ $i -le 100 ] ;do
sum=$(expr $sum + $i )
let i++
done
echo $sum



=======================



sum=0
i=1
while(( i <= 100 ))
do
let "sum+=i"
let "i += 1"
done
echo "sum=$sum"





2、编写脚本,通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态,统计在线主机和离线主机各多少。



whilenetstatus.sh



read -p "Please Input network:" a
i=0
j=0
k=0
while [ $i -le 255 ];do
ping -c1 -W1 $a$i &> /dev/null
if [ $? -eq 0 ];then
echo "$a$i is active"
let j++
else
echo "$a$i is inactive"
let k++
fi
let i++
done
echo "the sum number of active users is $j"
echo "the sum number of inactive users is $k"





3、编写脚本,打印九九乘法表



while3.sh



i=1
while [ $i -le 9 ];do
j=1
while [ $j -le $i ];do
mul=$[$i*$j]
echo -ne "$i*$j=$mul\t"
j=$[$j+1]
done
echo
i=$[$i+1]
done



==========================================



i=1
j=1
while [ "$i" -ne 10 ]
do
while [ "$j" -ne 10 ]
do
((product=$i*$j))
echo -ne $i\*$j=$product"\t"
((j++))
done
j=1
((i++))
echo
done
exit 0






4、编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者



random.sh



cat /dev/null > /root/random.txt
declare -i num=1
while [ $num -le 10 ];do
echo $RANDOM | tee -a /root/random.txt
let num++
done
echo "min: "
sort -n /root/random.txt | head -1
echo "max: "
sort -n /root/random.txt | tail -1



============================================



addr.sh



i=10
a=$RANDOM
max=$a
min=$a
while [ $i -ge 1 ]
do
[ $max -lt $a ] && max=$a
[ $min -gt $a ] && min=$a
echo "$a"
a=$RANDOM
let i--
done
echo "最大值$max"
echo "最小值$min"



============================================



declare -i MAX=0
declare -i MIN=0
for I in {1..10};do
MYRAND=$RANDOM
[ $I -eq 1 ] && MIN=$RANDOM
if [ $I -le 9 ];then
echo -n "$MYRAND,"
else
echo "$MYRAND"
fi
[ $MYRAND -gt $MAX ] && MAX=$MYRAND
[ $MYRAND -lt $MIN ] && MIN=$MYRAND
done
echo $MAX,$MIN





5、编写脚本,实现打印国际象棋棋盘



xiangqi



i=1
while [ $i -le 8 ];do
j=1
while [ $j -le 8 ];do
sum=`expr $i + $j`
z=`expr $sum % 2`
[ $z -eq 0 ] && echo -ne "\033[41;1m \033[0m"||echo -ne "\033[43;1m \033[0m"
let j++
done
echo
let i++
done



===================================



while5



declare -i i=1
declare -i j=1
while [ $i -lt 9 ];do
if [ $[$i%2] -eq 0 ] ;then
while [ $j -lt 9 ];do
if [ $[$j%2] -ne 0 ];then
echo -en "\e[43;37m \e[0m"
else
echo -en "\e[45;37m \e[0m"
fi
let j++
done
else
while [ $j -lt 9 ];do
if [ $[$j%2] -eq 0 ];then
echo -en "\e[43;37m \e[0m"
else
echo -en "\e[45;37m \e[0m"
fi
let j++
done
fi
declare -i j=1
let i++
echo ""
done
unset i;unset j





untill脚本



#!/bin/bash
i=1
until [ $i -ge 10 ]
do
echo $i
let i++

done





循环控制脚本



1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并提示该用户退出系统。



untilremind.sh



until who |grep -q "^hacker\b" ;do
sleep 3
done
who | grep "^hacker"|tr -s ' '|cut -d' ' -f3,5 >> /var/log/login.log
echo "you should logout system" | mail hacker
echo "reminded and login record in /var/log/login.log"





2、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出。



cai.sh



#!/bin/bash
suiji=$[$RANDOM%10+1]
read -p "我猜:" shuru
until [[ $suiji -eq $shuru ]]; do
[ $shuru -lt $suiji ] && echo "小了"
[ $shuru -gt $suiji ] && echo "大了"
read -p "我猜:" shuru
done
echo "猜中了,退出"



============================================



numberguess.sh



MAX=50
guess=1
let answer=($RANDOM % $MAX)
let answer+=1
ceiling=$MAX
floor=0
guesses=0

until [ "$guess" -eq "$answer" ]
do
echo "The magic number is between $floor and $ceiling."
echo -en "Make your guess:"
read guess
guesses=`expr $guesses + 1`
if [ "$guess" -lt "$answer" ];then
echo "$guess is too low"
if [ "$guess" -gt "$floor" ];then
floor=`expr $guess + 1`
fi
fi
if [ "$guess" -gt "$answer" ];then
echo "$guess is too hight"
if [ "$guess" -lt "$ceiling" ];then
ceiling=`expr $guess - 1`
fi
fi
done
echo "You got it in $guesses guesses!"





显示三角形
*
***
*****
*******



#!/bin/bash
read -p "Please Input line number:" Line
for ((i=1; i<=Line; i++))
do
for ((j=$Line-$i; j>0; j--));
do
echo -n ' '
done

for ((h=1; h<=$((2*$i-1)); h++))
do
echo -n '*'
done
echo
done



显示倒三角



#!/bin/bash
read -p "Please Input line number:" Line
for ((i=0; i<$Line; i++))
do
for ((j=$i; j>0; j--))
do
echo -n " "
done

for ((h=$((2*($Line-$i)-1)); h>0; h--))
do
echo -n "*"
done
echo
done





2、用until循环实现国际象棋棋盘



#!/bin/bash
i=1
until [ $i -gt 8 ];do
j=1
until [ $j -gt 8 ];do
sum=`expr $i + $j`
z=`expr $sum % 2`
[ $z -eq 0 ] && echo -ne "\033[41;1m \033[0m"||echo -ne "\033[43;1m \033[0m"
let j++
done
echo
let i++
done





while read line; do 循环体 done < FILE 依次读取文件每行给变量




计算UID总和



sum=0; while read line; do sum=$[sum+`echo $line|cut -d: -f3`]; done < /etc/passwd; echo $sum





扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功。



while read line;do
GECOS=$(echo $line | cut -d: -f5)
if [[-z "$GECOS"]]; then
name=$(echo $line | cut -d: -f1)

# echo $line | sed -r 's@:(:)@:用户名: '"$name"' 电话: 62985600\1@' #用sed替换也可以
chfn -f $name $name &>/dev/null
chfn -p 62985600 $name &> /dev/null
echo "$name GEGOS was modified"
fi
done < /etc/passwd





select 菜单



select abc in aa bb cc; do echo "$abc"; done



select abc in aa bb cc
do
case $abc in
aa)
echo "11"
;;
bb)
echo "22"
;;
*)
echo "00"
break
;;
esac
done



select abc
do
case $abc in
aa)
echo "$REPLY"
;;
bb)
echo "$REPLY"
;;
*)
echo "$REPLY"
break
;;
esac
done





countinue脚本



for i in {1..3}
do
for j in {10..20}
do
[ $j -eq 15 ]&&continue
echo $j
done
done



for i in {1..3}
do
for j in {10..20}
do
[ $j -eq 15 ]&&continue 2
echo $j
done
done



for i in {1..3}
do
for j in {10..20}
do
[ $j -eq 15 ]&&break
echo $j
done
done



for i in {1..3}
do
for j in {10..20}
do
[ $j -eq 15 ]&&break 2
echo $j
done
done





函数



# Evaluate shvar-style booleans
is_true() {
case "$1" in
[tT]|[yY]|[yY][eE][sS]|[tT][rR][uU][eE]
return 0
;;
esac
return 1
}



# Evaluate shvar-style booleans
is_false() {
case "$1" in
[fF]|[nN]|[nN][oO]|[fF][aA][lL][sS][eE]
return 0
;;
esac
return 1
}



function fun1 () { echo "abcdefg"; }
alias fun1=ls
fun1

unalias fun1
fun1
unset fun1
fun1

alias fun1=ls
function fun1 () { echo "abcdefg"; }
fun1

unset fun1
fun1
unalias fun1
fun1





函数自调用次数极限



fun() { let i++ ;echo $i; fun; }





函数递归



阶乘



#!/bin/bash
fact() {
if [ $1 eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*`fact $[$1-1]`]
fi
}
fact $1





函数


1、 编写服务脚本/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命令管理



usagte(){
echo "Usage: $prog {start|stop|restart|status}"
}


if [ $# -lt 1 ]; then
usage
exit 1
fi


start(){
if [ -e $lockfile ]; then
echo "$prog is already 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 "$prog is stopped yet."
fi
}


status(){
if [ -e $lockfile ]; then
echo "$prog is running."
else
echo "$prog is stopped."
fi
}


case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
usage
esac





2、 编写脚本/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退出



#!/bin/bash

ch_root="/mnt/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 $cmd_path ${ch_root}${bin_dir}
return 0
else
echo "Command not found."
return 1
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 $ {ch_root}${lib_dir} ] || mkdir -p ${ch_root}${lib_dir}
[ -f $ {ch_root}${loop} ] || cp $loop ${ch_root}${lib_dir}
done
}

read -p "Please input a command:" command

while [ "$command" != "quit" ]; do
if bincopy $command ; then
libcopy $command
fi
read -p "Please input a command or quit: "command
done





3、编写函数实现两个数字做为参数,返回最大值



#!/bin/bash
source funs.sh



funs.sh
#!/bin/bash
echo "please enter two number"
read a
read b
if test $a -eq $b
then echo "two same: "$a
elif test $a -gt $b
then echo "big is: "$a
else echo "big is: "$b
fi





4、编写函数实现数字的加减乘除运算,例如输入1 + 2,,将得出正确结果



#!/bin/bash
source funs.sh
jia $1 $2
jian $1 $2
cheng $1 $2
chu $1 $2



funs.sh
#!bin/bash
echo "1st arg is $1"
echo "2nd arg is $2"
jia (){
local a=$[$1+$2]
echo $a
}
jian (){
local a=$[$2-$1]
echo $a
}
cheng (){
local a=$[$1*$2]
echo $a
}
chu (){
local a=$[$1/$2]
echo $a
}





5、斐波那契数列又称黄金分割数列,因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列: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阶斐波那契数列



fact() {
if [ $1 -eq 0 ]
then
echo 0
elif [ $1 -eq 1 ]
then
echo 1
else
echo $[$(fact $[$1-2])+$(fact $[$1-1])]
fi
}





6、汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。利用函数,实现N片盘的汉诺塔的移动步骤



#!/bin/bash
step=0
hanoi(){
[[ ! $1 = ~ ^[1-9][0-9]*$ ]]&&echo "error! please input a positive interger" && exit
if [ $1 -eq 1 ]; then
let step++
echo "$step: move plate $1 $2 -----> $4"
else
hanoi "$[$1-1]" $2 $4 $3
let step++
echo "$step: move plate $1 $2 -----> $4"
hanoi "$[$1-1]" $3 $2 $4
fi
}
read -p "please input the number of plates: "number
hanoi $number A B C





数组



编写脚本,定义一个数组,数组中的元素是/var/log目录下所有以.log结尾的文件;要统计其下标为偶数的文件中的行数之和



#!/bin/bash
declare -a files
files=(/var/log/*.log)
for i in `seq0 $[${#files[*]}-1]`
do
fileline=`wc -l ${file[$i]} |cut -d " " -f1`
[ $[$i%2] -eq 0 ] && let lines+=$fileline
done
echo "Lines: $lines."



===================================================



#!/bin/bash
declare -a files
files=(/var/log/*.log)
declare -i lines=0
for i in $(seq0 $[${#files[*]}-1])
do
if [ $[$i%2] -eq 0 ];then
let lines+=$(wc-l ${files[$i]} | cut -d ' ' -f1)
fi
done
echo "Lines: $lines."





1、生成10个随机数,采用冒泡算法进行升序或降序排序



#!/bin/sh
echo "please input a number list:"
read -a arr



for (( i=0 ; i<${#arr[@]} ; i++ ))
do
for (( j=${#arr[@]}- 1 ; j>i ; j-- ))
do
#echo $j
if [[ ${arr[j]} -lt ${arr[j-1]} ]]
then
t=${arr[j]}
arr[j]=${arr[j-1]}
arr[j-1]=$t
fi
done
done
echo "after ascending sorting:"
echo ${arr[@]}



for (( i=0 ; i<${#arr[@]} ; i++ ))
do
for (( j=${#arr[@]}- 1 ; j>i ; j-- ))
do
#echo $j
if [[ ${arr[j]} -gt ${arr[j-1]} ]]
then
t=${arr[j]}
arr[j]=${arr[j-1]}
arr[j-1]=$t
fi
done
done
echo "after descending sorting:"
echo ${arr[@]}





1、让用户(管理员或所有用户)的PATH环境变量的值多出一个路径,例如多如/usr/local/apache2/bin



cd /etc/profile.d/
vim apache2.sh
PATH=$PATH:/usr/local/apache2/bin





2、用户wang登录时自动启用别名rm=‘rm –i’



vim .bashrc
alias rm=rm -i





3、用户登录时,显示红色字体的警示提醒信息“hi,dangerous!”



cd /etc/profile.d/
vim login.sh
echo -e "\033[31mdangerous\033[0m"