变量脚本
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[@]}