Linux 第九天: (08月11日) 练习和作业

 

 

变量脚本

 

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"