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

#!/bin/bash

HOST_NAME=`hostname`
IPV4_ADDR=`hostname -I`
OS_VERSION=`sed -rn '/^PRETTY_NAME="/s/^.*"(.*)"/\1/p' /etc/os-release`
KERNEL_VERSION=`uname -r`
CPU_TYPE=`lscpu  | sed -rn "s/^Model name: +(.*)$/\1/p"`
MEMORY=`free -h | awk 'NR==2{print $2}'`
DISK=`lsblk | awk '/^sd.*/{print $1,$4}'`

echo "HOST_NAME:${HOST_NAME}"
echo "IPV4_ADDR:${IPV4_ADDR}"
echo "OS_VERSION:${OS_VERSION}"
echo "KERNEL_VERSION:${KERNEL_VERSION}"
echo "CPU_TYPE:${CPU_TYPE}"
echo "MEMORY:${MEMORY}"
echo "DISK:${DISK}"

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

#!/bin/bash
if [ ! -e /backup ]; then 
    mkdir -p /backup
fi
cp -a  /etc/   /backup/etc`date +%F`

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

#!/bin/bash
echo "max is `df | awk '/^\/dev.*/{print $5}' | sort -nr | head -n1`"

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

#!/bin/bash

ss -t  | awk  '/^ESTAB/{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

5、 查看指定进程的环境变量

cat /proc/$PID/environ  # PID 是自己定义的变量,不是系统环境变量

6 鸡兔同笼,是中国古代著名典型趣题之一,记载于《孙子算经》之中。今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?

#!/bin/bash            
                       
HEADS=$1               
FEET=$2                
RABBITS=$((($FEET-$HEADS*2)/2))
CHICKENS=$(($HEADS-$RABBITS))
                       
echo "rabbits: $RABBITS"
echo "chickens: $CHICKENS" 

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

#!/bin/bash

(($# < 1)) && { echo "至少应该给一个参数"; exit 1; }
FILE_DIR=$1
if [ ! -e $FILE_DIR ]; then
    echo "文件不存在"
    exit 1
elif [ ! -f $FILE_DIR ]; then
    echo "文件不是普通文件, 无法打开"
    exit 1
fi

COUNT=`egrep -c  '^$'  "$FILE_DIR"`

echo "$FILE_DIR文件的空白行数是:$COUNT"

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

#!/bin/bash               
                          
(($# < 1)) && { echo "需要一个IPV4地址作为参数"; exit 1; }
                          
IP=$1                     
                          
if ping -c1 $IP &>/dev/null; then
    echo "$IP 可以访问"
else                      
    echo "$IP 不可访问"                                                           
fi 

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

#!/bin/bash                       
                                  
DISK_USED=`df | awk  '/^\/dev/{print $5}'  |tr -d "%" |sort -nr | head -n1`
INODE_USED=`df -i  | awk  '/^\/dev/{print $5}'  |tr -d "%" |sort -nr | head -n1`
                                  
if ((DISK_USED >= 80)); then   
    echo "disk space used exceed  80%" | wall &>/dev/null
elif ((INODE_USED >= 80)); then                                                                                                       
     echo "disk inode used exceed 80%" | wall &>/dev/null
fi 

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

#!/bin/bash
  
(($#<1)) && { echo "need 1 arg"; exit; }
FILE=$1
if [ ! -r $FILE -a ! -w $FILE  ]; then
    echo "yes, $USER can't read and write $FILE"
elif [ -r $FILE ]; then
    echo "No, $USER can read $FILE"
elif [ -w $FILE ]; then
    echo "No, $USER can write $FILE"
fi  

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

#!/bin/bash                          
                                     
(($#<1)) && { echo "need 1 arg"; exit; }
                                     
FILE=$1                              
                                     
if [ -f $1 ] && [[ $1 =~ ^.*\.sh$ ]]; then
    chmod +x $FILE                   
else                                 
    echo "$FILE is not script file"                                               
fi 

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

#nologin.sh
#!/bin/bash
if [ ! -e /etc/nologin ]; then
    touch /etc/nologin
fi

#login.sh
if [ -e /etc/nologin ]; then
    rm -rf /etc/nologin
fi

13、让所有用户的PATH环境变量的值多出一个路径,例如:/usr/local/apache/bin

#!/bin/bash

PATH+=:/usr/local/apache/bin
export PATH


# 执行这个脚本使用 source  ./script.sh生效
#或则把这个脚本放到 /etc/profile.d目录下

14

用户 root 登录时,将命令指示符变成红色,并自动启用如下别名: 
rm=‘rm -icdnet=‘cd /etc/sysconfig/network-scripts/’
editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eth0’
editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 或 ifcfg-ens33 ’ (如果系统是
CentOS7)
#!/bin/bash

if [ $USER = root ]; then
    PS1='\[\e[1;31m\][\t \u@\h \W]\[\e[0m\]$ '
    alias rm='rm -i'
    alias cdnet='cd /etc/sysconfig/network-scripts/'
    alias editnet='vim /etc/sysconfig/network-scirpts/ifcfg-eth0'
fi

#把这个脚本放到/etc/profile.d目录下

15、任意用户登录系统时,显示红色字体的警示提醒信息“Hi,dangerous!”

#!/bin/bash

echo -e "\e[31;1mHi,dangerous!\e[0m"

#此脚本放到 /etc/profile.d目录下

16、编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等

#!/bin/bash
cat >> /etc/vimrc <<EOF
        call setline(1, "\#!/bin/bash")
        call setline(2, "################################")
        call setline(3, "# Author: ShayZhu")                
        call setline(4, "# Contact: [email protected]")       
        call setline(5, "# Version: 1.0.0")                 
        call setline(6, '# Date: ' . strftime('%Y-%m-%d'))
        call setline(7, '# Description:')                   
        call setline(8, '################################')                                     
        call setline(9, '')                                 
        call setline(10, '')
EOF

17、编写脚本 createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之。并设置初始密码为123456,显示添加的用户的id号等信息,在此新用户第一次登录时,会提示用户立即改密码,如果没有参数,就提示:请输入用户名

#!/bin/bash

(($#<1)) && { echo "need a user name as a arg"; exit; }
                                     
NAME=$1                                 
                                        
if getent passwd $NAME &>/dev/null; then
    echo "$NAME is exist!!!"            
else                                    
    useradd  "$NAME"                    
    echo "$NAME:123456" | chpasswd   
    passwd --expire $NAME &>/dev/null                                                           
    id $NAME                            
fi 

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

#!/bin/bash

(($# < 1)) && { echo "need 1 arg"; exit 1; }
 
INPUT=`tr '[[:upper:]]' '[[:lower:]]' <<< "$1" `
                                                                                                
case $INPUT in
    yes|y)
        echo "user input is yes!"
        ;;  
    n|no)
        echo "user input is no!"
        ;;  
    *)  
        echo "user input is other"
        ;;  
esac

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

#!/bin/bash

(($#<1)) && { echo "need 1 filepath argument"; exit; }
 
FILE_PATH=$1
 
if [ -h $FILE_PATH ]; then
    echo "$FILE_PATH is a link file"
elif [ -d $FILE_PATH ]; then
    echo "$FILE_PATH is directory"
elif [ -f "$FILE_PATH" ]; then
    echo "$FILE_PATH" is rugular  file
else                                                                                            
    echo "$FILE_PATH is other file "
fi

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

                                             
(($#<1)) && { echo "need 1 number arg"; exit; }
                                             
NUM=$1                                       
                                             
if [[ $NUM =~ ^\+?[0-9]+$ ]] && ((NUM != 0)); then                                                             
    echo "yes! $NUM is positive integer " 
else                                         
    echo "no!! $NUM is not positive integer "
fi  

23 面试题,计算1+2+3+…+100 的结果

#!/bin/bash

(($#<1)) && { echo "need 1 positive integer arg"; exit; }

NUM=$1

SUM=$(echo `seq -s+ 1  $1 ` | bc)

echo "1+2+3...$NUM = $SUM"

24 100以内的奇数之和

#!/bin/bash

(($#<1)) && { echo "need 1 positive integer arg"; exit; }

NUM=$1
SUM=0
for ((i=1; i < $NUM; ++i)); do
    if ((i%2==1)); then
        ((SUM+=i))
    fi
done

echo "odd sum between $NUM and 1 : $SUM"

25 九九乘法表

#!/bin/bash

for ((row=1; row<=9; ++row)); do
    for ((column=1;column<=row;++column)); do
        printf "%-12s"  "${column} x ${row} = $((column*row))"                                                                        
    done               
    echo               
done  

26 将指定目录下的文件所有文件的后缀改名为 bak 后缀

#!/bin/bash

(($#<2)) && { echo -e  "uage: <dir> <suffix>  [<--all>]\n --all:包括隐藏文件,缺省:不包括隐藏文件"; exit 1; }
 
DIR=$1
SUFFIX=$2
MODE=$3
 
 
if [ ! -d "$DIR" -o "$MODE" != "--all" -a "$MODE" != "" ]; then
    echo "arg error!!!!"
    exit 1
fi
 
if [ "$MODE" = "--all" ]; then
    for file in `ls -A $DIR/`; do
        mv "$DIR/$file"  "${DIR}/${file%.*}.${SUFFIX#*.}"
    done                                                                                                                              
elif [ "$MODE" = "" ]; then
    for file in $DIR/*; do
        mv "$file"  "${file%.*}.${SUFFIX#*.}"
    done
fi

27 要求将目录YYYY-MM-DD/中所有文件,移动到YYYY-MM/DD/下

#!/bin/bash

DIR1=$1
DIR2=$2

mkdir -p "$DIR2"

cp -a "$DIR1/*"  "$DIR2"

28 扫描一个网段:10.0.0.0/24,判断此网段中主机在线状态,将在线的主机的IP打印出来

#!/bin/bash

IP=10.0.0.0                                                
                                                           
for i in {1..254}; do                                      
   { ping -c1 "${IP%.*}.$i" &>/dev/null && echo "${IP%.*}.$i is up" ; } &                                      
done                                                       
                                                           
wait 

29 有若干只兔和鸡,兔和鸡加起来一共有100条腿,请写一个简单的shell算出兔和鸡各多少只可能组合(假设所有的羊和鸡的腿都是健全的,且兔和鸡至少为1只)

#!/bin/bash

                                    
LEGS=100                            
for((rabbit=1; 4*rabbit <= 98; ++rabbit)); do
    if (((100 - rabbit * 4) % 2 == 0)); then
        ((possibles+=1))            
        echo "rabbits:${rabbit}, chickens:$(((100 - rabbit * 4) / 2))"
    fi                              
done                                
                                    
echo "total possibles: $possibles" 

30 等腰三角形

#!/bin/bash

(($#<1)) && { echo "need 1 arg"; exit; }
LEVEL=$1 
for((i=1; i <= LEVEL; ++i)); do
    for ((j=1; j <= LEVEL - i; ++j)); do
        echo -n " "
    done 
    for ((k=1; k<=i; ++k )); do
        echo -n "* "
    done 
    echo                                                                                                       
done 

31 生成进度

#!/bin/bash


for ((i = 1; i <= 100; ++i)); do
    echo -n "["
    for ((j=1; j <= i; ++j)); do
         echo -n "#"
    done          
    for ((k=1; k<=100-i;++k)); do
        echo -n " "                                                                                            
    done       
    echo -n "]"
    printf "%+4s" "$i%"
    sleep 0.1  
    echo -en "\r"
done           
echo 

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

#!/bin/bash
 
DIR=/var/

for FILE_PATH in $DIR/*; do 
    if [ -h $FILE_PATH ]; then
        echo "$FILE_PATH is a link file"
    elif [ -d $FILE_PATH ]; then
        echo "$FILE_PATH is directory"
    elif [ -f "$FILE_PATH" ]; then
        echo "$FILE_PATH" is rugular  file
    elif [ -p "$FILE_PATH" ]; then                                                                                            
        echo "$FILE_PATH is pipe file "
    elif [ -b "$FILE_PATH" ]; then   
        echo "$FILE_PATH is block device file "
    elif [ -c "$FILE_PATH" ]; then   
        echo "$FILE_PATH is character device file "
    elif [ -S "$FILE_PATH" ]; then   
        echo "$FILE_PATH is socket file "
    else
        echo "$FILE_PATH is other file "
    fi
done

33、添加10个用户user1-user10,密码为8位随机字符

#!/bin/bash
                                     
for NAME in user{1..10}; do
    if getent passwd $NAME &>/dev/null; then
        echo "$NAME is exist!!!"            
    else                                    
        useradd  "$NAME"
        PASSWD=$(cat  /dev/urandom  | tr -dc '[[:alnum:],./?;)(*&%$#@!~)-]' | head -c8)    
        echo "$NAME:$PASSWD" | tee -a  ./addUsers.txt |  chpasswd   
        passwd --expire $NAME &>/dev/null                                                           
        id $NAME                            
    fi 
done

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


#!/bin/bash

FILE_PATH=/etc/rc.d/rc3.d

for file in $FILE_PATH/*; do
    file=${file##*/}
    if [[ "$file" =~ ^K ]]; then
        echo "${file}stop"
    elif  [[ "$file" =~ ^S ]]; then
        echo "${file}start"
    fi
done

38、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:3AbCdeFgH.html

#!/bin/bash

FILE_PATH=/testdir

mkdir -p "$FILE_PATH"
for i in {1..10}; do
    touch $FILE_PATH/$i$(cat  /dev/urandom  | tr -dc '[[:alpha:]]' | head -c8).html
done

39 猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少?

#!/bin/bash

PEACHES=1                         
for ((i=1; i<=9; ++i)); do        
    ((PEACHES=(PEACHES+1)*2))  
done                              
                                  
echo "totle peaches is $PEACHES"

40 后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机执行命令: echo $RANDOM|md5sum|cut -c1-10 后的结果,请破解这些字符串对应的RANDOM值

#!/bin/bash

#random 范围 0 - 32767
declare -A VALUE=([efbaf275cd]='efbaf275cd' [4be9c40b8b]='4be9c40b8b' [44b2395c46]='44b2395c46' [f8c8873ce0]='f8c8873ce0' [b902c16c8b]='b902c16c8b' [ad865d2f63]='ad865d2f63')
for ((i=0; i<= 32767; ++i)); do
    HASH=`echo $i | md5sum | cut -c1-10`
    if [ "${VALUE[$HASH]}" ]; then
        echo "$i --> $HASH"
    fi
done

#1000 --> ad865d2f63
#3000 --> b902c16c8b
#6000 --> f8c8873ce0
#9000 --> 44b2395c46
#12000 --> 4be9c40b8b
#15000 --> efbaf275cd

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

#!/bin/bash
NAME=hacker
LOG_PATH=/var/log/login.log

while true; do
    if who | awk '{print $1}' | egrep "$NAME" &>/dev/null; then
        who | egrep "^hacker"  >> $LOG_PATH
        break
    fi
    sleep 3
done

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

#!/bin/bash
NUM=$((RANDOM % 10))

while true; do
    read -r -p "your number: " GUESS_NUM
    if ((GUESS_NUM == NUM)); then
        echo "congratulation!!!! The num is $NUM"
        break
    elif ((GUESS_NUM > NUM)); then
        echo "sorry! your num is greater"
    elif ((GUESS_NUM < NUM)); then
        echo "sorry! your num is lower"
    fi
done

43、用文件名做为参数,统计所有参数文件的总行数

#!/bin/bash

LINES=0
for file in "$@"; do
    if [ -f "$file" ]; then
        ((LINES+=$(cat "$file" | wc -l))) 
    fi
done

echo "total lines is $LINES"

44、用二个以上的数字为参数,显示其中的最大值和最小值

#!/bin/bash

MIN=$1
MAX=$2

for i ; do
    if ((MIN > $1)); then
        MIN=$1
    fi
    if ((MAX < $1)); then
        MAX=$1
    fi
    shift
done

echo "MAX : $MAX, MIN: $MIN"

45、 编写函数,实现OS的版本判断

#!/bin/bash

os_version()
{
    sed -rn '/^PRETTY_NAME="/s/^.*"(.*)"/\1/p' /etc/os-release
}

46、 编写函数,实现取出当前系统eth0的IP地址

#!/bin/bash

eth0_ip()
{
    ifconfig eth0 | awk 'NR==2{print $2}'
}

47、 编写函数,实现打印绿色OK和红色FAILED

#!/bin/bash


#color output #1:color  #2:content
color_output() 
{
    if (($# == 0)); then
        return 1
    fi
    case $1 in
        red)
            echo -ne "\e[1;31m$2\e[0m"
            ;;
        green)
            echo -ne "\e[1;32m$2\e[0m"
            ;;
        yellow)
            echo -ne "\e[1;33m$2\e[0m"
            ;;
        *)
            echo -ne "\e[1;37m$2\e[0m"
            ;;
    esac
}


#print message $1:message
print_message() {

    if (($? == 0)); then
        local space=$((80-${#1}))
        echo -n  "$1"
        printf "%${space}s\n"  "$(color_output green "[ok]")"
    else 
        local space=$((80-${#1}))
        echo -n  "$1"
        printf "%${space}s\n"  "$(color_output red "[failed]")"
        exit 1
    fi
}

48、 编写函数,实现判断是否无位置参数,如无参数,提示错误

#!/bin/bash

check_position_arg() 
{
    (($# < 1 )) && { echo "error! no position args!"; return 1; }
}

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

#!/bin/bash

max_in_two()
{
    (($1 > $2)) && echo "$1" || echo "$2"
}

52、

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

f()
{
    local n=$1
    if ((n==0)); then
        echo '0'
        return 0
    elif ((n==1)); then
        echo '1'
        return 0
    fi
    echo $((`f $[n-1]` + `f $[n-2]`))
    return 0
}

f 10

53、

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

#!/bin/bash

       
move() 
{      
    local A=$1  #存有盘子的柱子
    local B=$2  #中间临时柱子
    local C=$3  #盘子需要被移动到的目标柱子
    local n=$4  #目前盘子数量
       
    ((n==1)) && { echo "$A --> $C"; return 0; }
    move $A $C $B $[n-1]   #n-1 A移动到B 
    echo "$A --> $C"    #A 移动到C
    move $B $A $C $[n-1]   #n-1 B移动到C
}      
       
move A B C  "$1"  # $1 初始盘子数量

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

#!/bin/bash

DIR=/var/log
declare -a arr

for file in $DIR/*; do
    if [[ $file =~ \.log$ ]]; then
        arr[${#arr[*]}]=$file
    fi
done

SUM=0

for i in ${!arr[*]}; do
    if ((i % 2 == 0)); then
        ((SUM+=$(cat ${arr[i]} | wc -l)))
    fi 
done

echo "even index file, total lines is $SUM "