shell脚本练习

1.判断指定进程的运行情况

#!/bin/bash
NAME=httpd #这里输入进程的名称
NUM=$(ps -ef |grep $NAME |grep -vc grep)
if [ $NUM -eq 1 ]; thenecho "$NAME running."
elseecho "$NAME is not running!"
fi

2.判断用户是否存在

#!/bin/bash
read -p "请输入用户:" user
for i in `awk -F :  '{print $1}' /etc/passwd`
doif [ $i == $user ]thenecho "用户已存在!"exitelseisfind=falsefi
done
echo "用户不存在!"

3.生成随机数

#!/bin/bash
read -p "请输入随机生成的数字位数:" num
echo $RANDOM | cksum | cut -c 1-$num

4.判断软件包是否安装

#!/bin/bash
read -p "请输入要查询的软件包:" softwareif rpm -q $software &>/dev/null ;thenecho "软件包已经安装!"elseecho "软件包未安装!"fi

5.判断主机是否存活

ip_list="192.168.254.1 192.168.254.10" #定义一个主机列表
for ip in $ip_list;doNUM=1while [ $NUM -le 3 ];doif ping -c 1 $ip > /dev/null;thenecho "$ip 存在于网络中!"breakelseecho "$ip 不存在于网络中!"breakfidone
done

6.判断指定主机端口状态

HOST=127.0.0.1 #被扫描主机
PORT="22 80 8080" #指定需要扫描的端口
for PORT in $PORT; do #进行for循环if echo &>/dev/null > /dev/tcp/$HOST/$PORT; thenecho    "$PORT open"elseecho    "$PORT close"fi
done

7.获取主机IP地址

#!/bin/bash
IP=$(ip address show | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
echo "$IP"

8.判断文件或目录是否存在

#!/bin/bashif [ $# -eq 0 ];thenecho "未输入任何参数,请输入参数"echo "用法:$0 [文件名 | 目录名]"
fiif [ -f $1 ]; thenecho "该文件 存在"ls -l $1
elif [ -d $1 ]; thenecho "该目录 存在"ls -ld $1
elseecho "该文件or目录 不存在"
fi

9.显示系统信息

#!/bin/bash
#
HOSTNAME=`hostname`
IP=`ip a show ens33 | grep "inet" | grep -v "inet6" | awk '{print $2}' | cut -d'/' -f1`
SYSTEM=`cat /etc/centos-release`
CORE=`uname -r`
CPU=`cat /proc/cpuinfo | grep 'model name' |uniq | cut -d: -f2`
MEMORY=`free -mh | grep -i "mem" | awk '{print$2}'`
DISKNUM=`fdisk -l | grep -i "/dev" | grep -i "disk" | wc -l`
systemname=("HOSTNAME" "IP" "SYSTEM VERSION" "CORE VERSION" "CPU" "MEMORY SIZE")
systeminfo=("$HOSTNAME" "$IP" "$SYSTEM" "$CORE" "$CPU" "$MEMORY")
for s in `seq 1 $DISKNUM`;doeval DISK$s=`fdisk -l | grep -i "/dev" | grep -i "disk" | head -$s | tail -1|  awk '{print $2$3$4}' | cut -d',' -f1`eval systeminfo[$(($s+5))]='$'DISK$ssystemname[$(($s+5))]="DISK$s SIZE"
done
for i in ${!systeminfo[*]};doecho "--------------------------------------------------------------"printf "|%-15s| %-43s|\n" "${systemname[$i]}" "${systeminfo[$i]}"
done
echo "--------------------------------------------------------------"

10.判断输入的是否为IP地址

#!/bin/bash
IP=$1
if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; thenFIELD1=$(echo $IP|cut -d. -f1)FIELD2=$(echo $IP|cut -d. -f2)FIELD3=$(echo $IP|cut -d. -f3)FIELD4=$(echo $IP|cut -d. -f4)if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; thenecho "$IP 是一个IP地址!"elseecho "$IP 不是一个IP地址!"fielseecho "IP地址格式错误!"
fi

11.sys_info.sh

#!/bin/bashlocalip=$(ifconfig ens33 | grep netmask | tr -s " " | cut -d " " -f3)
mem=$(free | grep Mem | tr -s " " | cut -d " " -f7)
cpu=$(uptime | tr -s " " | cut -d " " -f11)echo "IP address:$localip"
echo "Memory surplus:$mem"
echo "CPU load:$cpu"

12、测试计算机的CPU品牌是AMD还是Intel

cpu_info.sh

#!/bin/bashif grep -q AMD /proc/cpuinfo; then
echo "AMD CPU"fiif grep -q Intel /proc/cpuinfo; thenecho "Intel CPU"
fi

13、服务状态监控

check_service.sh

#!/bin/bashif [ -z $1 ];thenecho "error:No server name was entered"echo "Usage: script name   +   server name"exitfiif systemctl is-active $1 &>/dev/null; thenecho "$1 have already started"
elseecho "$1 unstart"fiif systemctl is-enabled $1 &>/dev/null; thenecho "$1 Is the boot auto option"
elseecho "$1 Not start auto option"
fi  

14、通过读取位置变量,实现分区管理工作

#!/bin/bashif [ $# -ne 2 ];thenecho -e "usage: <disk name> <create|new|remove|query>"exit
fi#测试磁盘是否存在if [ ! -b $1 ];thenecho -e "disk nonentity"exit
fi#根据不同的指令对磁盘进行分区管理if [[ $2 == create ]];thenparted -s $1 mklabel gpt
elif [[ $2 == new ]];thenparted -s $1 mkpart primary 1 100%
elif [[ $2 == remove ]];thenparted -s $1 rm 1
elif [[ $2 == query ]];thenparted -s $1 print
elseclearecho -e "operation error"echo "use:[create|new|remove|query]."
fi

15、查看系统信息的脚本

#!/bin/bashecho "输入一个选项"select item in "CPU" "IP" "MEM" "exit"
docase $item in"CPU")uptime;;"IP")ip a s;;"MEM")free;;"exit")exit;;*)echo error;;esac
done

16、通过文件重定向读取文件解决子shell问题

#!/bin/bashtmp_file="/tmp/subshell-?.txt"
df | grep "^/" > $tmp_file
while read name total used free other
dolet sum+=free
done < $tmp_file
rm -rf $tmp_file
echo $sum

17、多进程的ping脚本

本脚本的功能就是使用函数与&后台进程实现多进程ping测试。

#!/bin/bashnet="192.168.43"
multi_ping_fun(){ping -c2 -i0.2 -W1 $1 &>/dev/nullif [ $? -eq 0 ];thenecho "$1 is up"elseecho "$1 is down"fi
}for i in {1..254}
domulti_ping_fun $net.$i &
done
#!/bin/bashnet="192.168.43"
multi_ping_fun(){ping -c2 -i0.2 -W1 $1 &>/dev/nullif [ $? -eq 0 ];thenecho "$1 is up"elseecho "$1 is down"fi
}#通过循环反复调用函数并将其放入后台并行执行
for i in {1..254}
domulti_ping_fun $net.$i &
done
wait

18、循环对多个文件进行备份操作

#!/bin/bashfor i in `ls /etc/*.conf`
dotar -czf /home/minger/share/tencent/shell/$(basename $i).tar.gz $i
done

19、使用进程号或进程数量生成随机数

#!/bin/bash#根据进程号生成随机文件touch /tmp/?.tmp#根据进程数量生成随机文件pnum=`ps aux | wc -l`
touch /tmp/$pnum.tmp#根据文件个数生成随机文件fnum=`find /etc | wc -l`
touch /tmp/$fnum.tmp#根据文件行数生成随机文件cnum=`cat /var/log/messages | wc -l`
touch /tmp/$cnum.tmp

20、Shell 版本的进度条功能

#!/bin/bash#防止提前按Ctrl +C 组合键后无法结束进度条trap 'kill $!' INTbar(){while :doecho -n '#'sleep 0.3done
}bar &
cp -r $1 $2
kill $!
echo "复制结束!"

21使用Hydra配合脚本批量暴力破解

#!/bin/bash
random=$RANDOMif [ $# -lt 4 ]
thenecho "usage: ./hydra-ssh.sh -u root -p ./passwd.txt -s 22 -x ssh -f ./iplist.txt"echo "usage: ./hydra.sh -u root -p ./passwd.txt -s 22 -x ssh -l 192.168.9.0/24"exit 1
fiwhile [ -n "$1" ]
do  case "$1" in    -u)  user=$2shift  ;;  -p)  passfile=$2shift  ;;  -s)  port=$2shift  ;; -x)  term=$2shift  ;; -f)  cat $2 > /tmp/IPaddress-output-$random.txtshift  ;;  -l)  nmap -vv -n -sS -sU -p$port $2  | grep "Discovered open port" | awk {'print $6'} | awk -F/ {'print $1'} > /tmp/IPaddress-output-$random.txt shift  ;; *)  echo "$1 is not an option"  echo "usage: ./hydra.sh -u root -p ./passwd.txt -s 22 -x ssh -f ./iplist.txt"echo "usage: ./hydra.sh -u root -p ./passwd.txt -s 22 -x ssh -l 192.168.9.0/24"exit 1;;  esac  shift
doneecho "-----------Port Scan Finished-----------" >> ./Result-hydra.txtchmod 666 /tmp/IPaddress-output-$random.txtcat /tmp/IPaddress-output-$random.txt | while read line
do echo "Current Task: ${line}" >> ./Result-hydra.txthydra -q -l $user -P $passfile -t 4 -vV -s $port $line $term | grep "host:" >> ./Result-hydra.txt
doneecho "-------Password Guessing Finished-------" >> ./Result-hydra.txtrm -rf /tmp/IPaddress-output-$random.txt
cat ./Result-hydra.txt | grep "host:"

22Linux 系统发送告警脚本

# yum install mailx
# vi /etc/mail.rc
set from=baojingtongzhi@163.com smtp=smtp.163.com
set smtp-auth-user=baojingtongzhi@163.com smtp-auth-password=123456
set smtp-auth=login

23MySQL 数据库备份单循环

#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
DB_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "show databases;" 2>/dev/null |egrep -v "Database|information_schema|mysql|performance_schema|sys")for DB in $DB_LIST; doBACKUP_NAME=$BACKUP_DIR/${DB}_${DATE}.sqlif ! mysqldump -h$HOST -u$USER -p$PASS -B $DB > $BACKUP_NAME 2>/dev/null; thenecho "$BACKUP_NAME 备份失败!"fi
done

24MySQL 数据库备份多循环

#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
DB_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "show databases;" 2>/dev/null |egrep -v "Database|information_schema|mysql|performance_schema|sys")for DB in $DB_LIST; doBACKUP_DB_DIR=$BACKUP_DIR/${DB}_${DATE}[ ! -d $BACKUP_DB_DIR ] && mkdir -p $BACKUP_DB_DIR &>/dev/nullTABLE_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "use $DB;show tables;" 2>/dev/null)for TABLE in $TABLE_LIST; doBACKUP_NAME=$BACKUP_DB_DIR/${TABLE}.sqlif ! mysqldump -h$HOST -u$USER -p$PASS $DB $TABLE > $BACKUP_NAME 2>/dev/null; thenecho "$BACKUP_NAME 备份失败!"fidone
done

25Nginx 访问日志按天切割

#!/bin/bash
LOG_DIR=/usr/local/nginx/logs
YESTERDAY_TIME=$(date -d "yesterday" +%F)
LOG_MONTH_DIR=$LOG_DIR/$(date +"%Y-%m")
LOG_FILE_LIST="default.access.log"for LOG_FILE in $LOG_FILE_LIST; do[ ! -d $LOG_MONTH_DIR ] && mkdir -p $LOG_MONTH_DIRmv $LOG_DIR/$LOG_FILE $LOG_MONTH_DIR/${LOG_FILE}_${YESTERDAY_TIME}
donekill -USR1 $(cat /var/run/nginx.pid)

26Nginx 访问日志分析脚本

#!/bin/bash
# 日志格式: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"
LOG_FILE=$1
echo "统计访问最多的10个IP"
awk '{a[$1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}' $LOG_FILE |sort -k2 -nr |head -10
echo "----------------------"echo "统计时间段访问最多的IP"
awk '$4>="[01/Dec/2018:13:20:25" && $4<="[27/Nov/2018:16:20:49"{a[$1]++}END{for(v in a)print v,a[v]}' $LOG_FILE |sort -k2 -nr|head -10
echo "----------------------"echo "统计访问最多的10个页面"
awk '{a[$7]++}END{print "PV:",length(a);for(v in a){if(a[v]>10)print v,a[v]}}' $LOG_FILE |sort -k2 -nr
echo "----------------------"echo "统计访问页面状态码数量"
awk '{a[$7" "$9]++}END{for(v in a){if(a[v]>5)print v,a[v]}}'

27查看网卡实时流量脚本

#!/bin/bash
NIC=$1
echo -e " In ------ Out"
while true; doOLD_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)OLD_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)sleep 1NEW_IN=$(awk  '$0~"'$NIC'"{print $2}' /proc/net/dev)NEW_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)IN=$(printf "%.1f%s" "$((($NEW_IN-$OLD_IN)/1024))" "KB/s")OUT=$(printf "%.1f%s" "$((($NEW_OUT-$OLD_OUT)/1024))" "KB/s")echo "$IN $OUT"sleep 1
done

28服务器系统配置初始化脚本

#/bin/bash
# 设置时区并同步时间
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
if ! crontab -l |grep ntpdate &>/dev/null ; then(echo "* 1 * * * ntpdate time.windows.com >/dev/null 2>&1";crontab -l) |crontab
fi# 禁用selinux
sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config# 关闭防火墙
if egrep "7.[0-9]" /etc/redhat-release &>/dev/null; thensystemctl stop firewalldsystemctl disable firewalld
elif egrep "6.[0-9]" /etc/redhat-release &>/dev/null; thenservice iptables stopchkconfig iptables off
fi# 历史命令显示操作时间
if ! grep HISTTIMEFORMAT /etc/bashrc; thenecho 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/bashrc
fi# SSH超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null; thenecho "export TMOUT=600" >> /etc/profile
fi# 禁止root远程登录
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config# 禁止定时任务向发送邮件
sed -i 's/^MAILTO=root/MAILTO=""/' /etc/crontab# 设置最大打开文件数
if ! grep "* soft nofile 65535" /etc/security/limits.conf &>/dev/null; thencat >> /etc/security/limits.conf << EOF* soft nofile 65535* hard nofile 65535
EOF
fi# 系统内核优化
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_fin_timeout = 20
EOF# 减少SWAP使用
echo "0" > /proc/sys/vm/swappiness# 安装系统性能分析工具及其他
yum install gcc make autoconf vim sysstat net-tools iostat if

29监控 100 台服务器磁盘利用率脚本

#!/bin/bash
HOST_INFO=host.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); doUSER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)TMP_FILE=/tmp/disk.tmpssh -p $PORT $USER@$IP 'df -h' > $TMP_FILEUSE_RATE_LIST=$(awk 'BEGIN{OFS="="}/^\/dev/{print $NF,int($5)}' $TMP_FILE)for USE_RATE in $USE_RATE_LIST; doPART_NAME=${USE_RATE%=*}USE_RATE=${USE_RATE#*=}if [ $USE_RATE -ge 80 ]; thenecho "Warning: $PART_NAME Partition usage $USE_RATE%!"fidone
done

30通过位置变量创建 Linux 系统账户及密码

#!/bin/bash
# 通过位置变量创建 Linux 系统账户及密码
#$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数
useradd "$1"
echo "$2" | passwd ‐‐stdin "$1"

31备份日志

#!/bin/bash
# 每周 5 使用 tar 命令备份/var/log 下的所有日志文件
# vim /root/logbak.sh
# 编写备份脚本,备份后的文件名包含日期标签,防止后面的备份将前面的备份数据覆盖
# 注意 date 命令需要使用反引号括起来,反引号在键盘<tab>键上面
tar -czf    log-`date +%Y%m%d`.tar.gz    /var/log
# crontab ‐e    #编写计划任务,执行备份脚本
00  03  *   *   5   /root/logbak.sh

32一键部署 LNMP(RPM 包版本)

#!/bin/bash
# 一键部署 LNMP(RPM 包版本)
# 使用 yum 安装部署 LNMP,需要提前配置好 yum 源,否则该脚本会失败
# 本脚本使用于 centos7.2 或 RHEL7.2
yum ‐y install httpd
yum ‐y install mariadb mariadb‐devel mariadb‐server
yum ‐y install php php‐mysql
systemctl start httpd mariadb
systemctl enable httpd mariadb

33监控内存和磁盘容量,小于给定值时报警

#!/bin/bash
# 实时监控本机内存和硬盘剩余空间,剩余内存小于500M、根分区剩余空间小于1000M时,
#发送报警邮件给root管理员提取根分区剩余空间
disk_size=$(df / | awk '/\//{print $4}')
# 提取内存剩余空间
mem_size=$(free | awk '/Mem/{print $4}')
while :
do
# 注意内存和磁盘提取的空间大小都是以 Kb 为单位
if [ $disk_size -le 512000 -a $mem_size -le 1024000 ]
then
mail ‐s "Warning" root <<EOF
Insufficient resources,资源不足
EOF
fi
done

34猜数字游戏

#!/bin/bash
# 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,
# 猜小了或猜大了,直至用户猜对脚本结束。
# RANDOM 为系统自带的系统变量,值为 0‐32767的随机数
# 使用取余算法将随机数变为 1‐100 的随机数
num=$[RANDOM%100+1]
echo "$num"
# 使用 read 提示用户猜数字
# 使用 if 判断用户猜数字的大小关系:‐eq(等于),‐ne(不等于),‐gt(大于),‐ge(大于等于),
# ‐lt(小于),‐le(小于等于)
while :
do
read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai
if [ $cai -eq $num ]
then
echo "恭喜,猜对了"
exit
elif [ $cai -gt $num ]
then
echo "Oops,猜大了"
else
echo "Oops,猜小了"
fi
done

35检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不是,则提示您非管理员(使用字串对比版本)

#!/bin/bash
# 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不
# 是,则提示您非管理员(使用字串对比版本)
if [ $USER == "root" ]
then
yum ‐y install vsftpd
else
echo "您不是管理员,没有权限安装软件"
fi

36使用 UID 数字对比版本

#!/bin/bash
# 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不
# 是,则提示您非管理员(使用 UID 数字对比版本)
if [ $UID -eq 0 ];then
yum ‐y install vsftpd
else
echo "您不是管理员,没有权限安装软件"
fi

37编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默认的 123456 作为默认密码。

#!/bin/bash
# 编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户
# 不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默
# 认的 123456 作为默认密码。
read -p "请输入用户名: " user
#使用‐z 可以判断一个变量是否为空,如果为空,提示用户必须输入账户名,并退出脚本,退出码为 2
#没有输入用户名脚本退出后,使用$?查看的返回码为 2
if [ -z $user ];then
echo "您不需输入账户名"
exit 2
fi
#使用 stty ‐echo 关闭 shell 的回显功能
#使用 stty echo 打开 shell 的回显功能
stty -echo
read -p "请输入密码: " pass
stty echo
pass=${pass:‐123456}
useradd "$user"
echo "$pass" | passwd ‐‐stdin "$user"

38输入三个数并进行升序排序

#!/bin/bash
# 依次提示用户输入 3 个整数,脚本根据数字大小依次排序输出 3 个数字
read -p "请输入一个整数:" num1
read -p "请输入一个整数:" num2
read -p "请输入一个整数:" num3
# 不管谁大谁小,最后都打印 echo "$num1,$num2,$num3"
# num1 中永远存最小的值,num2 中永远存中间值,num3 永远存最大值
# 如果输入的不是这样的顺序,则改变数的存储顺序,如:可以将 num1 和 num2 的值对调
tmp=0
# 如果 num1 大于 num2,就把 num1 和和 num2 的值对调,确保 num1 变量中存的是最小值
if [ $num1 -gt $num2 ];then
tmp=$num1
num1=$num2
num2=$tmp
fi
# 如果 num1 大于 num3,就把 num1 和 num3 对调,确保 num1 变量中存的是最小值
if [ $num1 -gt $num3 ];then
tmp=$num1
num1=$num3
num3=$tmp
fi
# 如果 num2 大于 num3,就把 num2 和 num3 对标,确保 num2 变量中存的是小一点的值
if [ $num2 -gt $num3 ];then
tmp=$num2
num2=$num3
num3=$tmp
fi
echo "排序后数据(从小到大)为:$num1,$num2,$num3"

39石头、剪刀、布游戏

#!/bin/bash
# 编写脚本,实现人机<石头,剪刀,布>游戏
game=(石头 剪刀 布)
num=$[RANDOM%3]
computer=${game[$num]}
# 通过随机数获取计算机的出拳
# 出拳的可能性保存在一个数组中,game[0],game[1],game[2]分别是 3
#中不同的可能
echo "请根据下列提示选择您的出拳手势"
echo "1.石头"
echo "2.剪刀"
echo "3.布"
read -p "请选择 1‐3:" person
case $person in
1)
if [ $num -eq 0 ]
then
echo "平局"
elif [ $num -eq 1 ]
then
echo "你赢"
else
echo "计算机赢"
fi;;
2)
if [ $num -eq 0 ]
then
echo "计算机赢"
elif [ $num -eq 1 ]
then
echo "平局"
else
echo "你赢"
fi;;
3)
if [ $num -eq 0 ]
then
echo "你赢"
elif [ $num -eq 1 ]
then
echo "计算机赢"
else
echo "平局"
fi;;
*)
echo "必须输入 1‐3 的数字"
esac

41编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(for 版本)

#!/bin/bash
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,
#哪些主机处于关机状态(for 版本)
for i in {1..254}
do
# 每隔0.3秒ping一次,一共ping2次,并以1毫秒为单位设置ping的超时时间
ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i &>/dev/null
if [ $? -eq 0 ];then
echo "192.168.4.$i is up"
else
echo "192.168.4.$i is down"
fi
done

42编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(while 版本)

#!/bin/bash
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,
#哪些主机处于关机状态(while 版本)
i=1
while [ $i -le 254 ]
do
ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i &>/dev/null
if [ $? -eq 0 ];then
echo "192.168.4.$i is up"
else
echo "192.168.4.$i is down"
fi
let i++
done

43编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(多进程版)

#!/bin/bash
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,
# 哪些主机处于关机状态(多进程版)
# 定义一个函数,ping 某一台主机,并检测主机的存活状态
myping(){
ping ‐c 2 ‐i 0.3 ‐W 1 $1 &>/dev/null
if [ $? -eq 0 ];then
echo "$1 is up"
else
echo "$1 is down"
fi
}
for i in {1..254}
do
myping 192.168.4.$i &
done
# 使用&符号,将执行的函数放入后台执行
# 这样做的好处是不需要等待ping第一台主机的回应,
#就可以继续并发ping第二台主机,依次类推。

44编写脚本,显示进度条

#!/bin/bash
# 编写脚本,显示进度条
jindu(){
while :
do
echo -n '#'
sleep 0.2
done
}
jindu &
cp -a $1 $2
killall $0
echo "拷贝完成"

45进度条,动态时针版本;定义一个显示进度的函数,屏幕快速显示| / ‐ \

#!/bin/bash
# 进度条,动态时针版本
# 定义一个显示进度的函数,屏幕快速显示| / ‐ \
rotate_line(){
INTERVAL=0.5 #设置间隔时间
COUNT="0" #设置4个形状的编号,默认编号为 0(不代表任何图像)
while :
do
COUNT=`expr $COUNT + 1`
#执行循环,COUNT 每次循环加 1,(分别代表4种不同的形状)
case $COUNT in #判断 COUNT 的值,值不一样显示的形状就不一样
"1") #值为 1 显示‐
echo -e '‐'"\b\c"
sleep $INTERVAL
;;
"2") #值为 2 显示\\,第一个\是转义
echo -e '\\'"\b\c"
sleep $INTERVAL
;;
"3") #值为 3 显示|
echo -e "|\b\c"
sleep $INTERVAL
;;
"4") #值为 4 显示/
echo -e "/\b\c"
sleep $INTERVAL
;;
*) #值为其他时,将 COUNT 重置为 0
COUNT="0";;
esac
done
}
rotate_line

46,9*9 乘法表

#!/bin/bash
# 9*9 乘法表(编写 shell 脚本,打印 9*9 乘法表)
for i in `seq 9`
do
for j in `seq $i`
do
echo -n "$j*$i=$[i*j] "
done
echo
done

47. 使用死循环实时显示 eth0 网卡发送的数据包流量

#!/bin/bash
# 使用死循环实时显示 eth0 网卡发送的数据包流量
while :
do
echo '本地网卡 eth0 流量信息如下: '
ifconfig eth0 | grep "RX pack" | awk '{print $5}'
ifconfig eth0 | grep "TX pack" | awk '{print $5}'
sleep 1
done

48使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息

#!/bin/bash
# 使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码
# 本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息
for i in `cat user.txt`
do
useradd $i
echo "123456" | passwd ‐‐stdin $i
done

49编写批量修改扩展名脚本

#!/bin/bash
# 编写批量修改扩展名脚本,如批量将 txt 文件修改为 doc 文件
# 执行脚本时,需要给脚本添加位置参数
# 脚本名 txt doc(可以将 txt 的扩展名修改为 doc)
# 脚本名 doc jpg(可以将 doc 的扩展名修改为 jpg)
for i in "ls *.$1"
do
mv $i ${i%.*}.$2
done

50使用 expect 工具自动交互密码远程其他主机安装 httpd 软件

#!/bin/bash
# 使用 expect 工具自动交互密码远程其他主机安装 httpd 软件
# 删除~/.ssh/known_hosts 后,ssh 远程任何主机都会询问是否确认要连接该主机
rm ‐rf ~/.ssh/known_hosts
expect <<EOF
spawn ssh 192.168.4.254
expect "yes/no" {send "yes\r"}
# 根据自己的实际情况将密码修改为真实的密码字串
expect "password" {send "密码\r"}
expect "#" {send "yum ‐y install httpd\r"}
expect "#" {send "exit\r"}
EOF

51一键部署 LNMP(源码安装版本)

#!/bin/bash
# 一键部署 LNMP(源码安装版本)
menu()
{
clear
echo " ##############‐‐‐‐Menu‐‐‐‐##############"
echo "# 1. Install Nginx"
echo "# 2. Install MySQL"
echo "# 3. Install PHP"
echo "# 4. Exit Program"
echo " ########################################"
}
choice()
{
read -p "Please choice a menu[1‐9]:" select
}
install_nginx()
{
id nginx &>/dev/null
if [ $? -ne 0 ];then
useradd -s /sbin/nologin nginx
fi
if [ -f nginx‐1.8.0.tar.gz ];then
tar -xf nginx‐1.8.0.tar.gz
cd nginx‐1.8.0
yum -y install gcc pcre‐devel openssl‐devel zlib‐devel make
./configure ‐‐prefix=/usr/local/nginx ‐‐with‐http_ssl_module
make
make install
ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
cd ..
else
echo "没有 Nginx 源码包"
fi
}
install_mysql()
{
yum -y install gcc gcc‐c++ cmake ncurses‐devel perl
id mysql &>/dev/null
if [ $? -ne 0 ];then
useradd -s /sbin/nologin mysql
fi
if [ -f mysql‐5.6.25.tar.gz ];then
tar -xf mysql‐5.6.25.tar.gz
cd mysql‐5.6.25
cmake .
make
make install
/usr/local/mysql/scripts/mysql_install_db ‐‐user=mysql ‐‐datadir=/usr/local/mysql/data/
‐‐basedir=/usr/local/mysql/
chown -R root.mysql /usr/local/mysql
chown -R mysql /usr/local/mysql/data
/bin/cp -f /usr/local/mysql/support‐files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
/bin/cp -f /usr/local/mysql/support‐files/my‐default.cnf /etc/my.cnf
echo "/usr/local/mysql/lib/" >> /etc/ld.so.conf
ldconfig
echo 'PATH=\$PATH:/usr/local/mysql/bin/' >> /etc/profile
export PATH
else
echo "没有 mysql 源码包"
exit
fi
}
install_php()
{
#安装 php 时没有指定启动哪些模块功能,
#如果的用户可以根据实际情况自行添加额外功能如‐‐with‐gd 等
yum -y install gcc libxml2‐devel
if [ -f mhash‐0.9.9.9.tar.gz ];then
tar -xf mhash‐0.9.9.9.tar.gz
cd mhash‐0.9.9.9
./configure
make
make install
cd ..
if [ ! ‐f /usr/lib/libmhash.so ];then
ln -s /usr/local/lib/libmhash.so /usr/lib/
fi
ldconfig
else
echo "没有 mhash 源码包文件"
exit
fi
if [ -f libmcrypt‐2.5.8.tar.gz ];then
tar -xf libmcrypt‐2.5.8.tar.gz
cd libmcrypt‐2.5.8
./configure
make
make install
cd ..
if [ ! -f /usr/lib/libmcrypt.so ];then
ln -s /usr/local/lib/libmcrypt.so /usr/lib/
fi
ldconfig
else
echo "没有 libmcrypt 源码包文件"
exit
fi
if [ -f php‐5.4.24.tar.gz ];then
tar -xf php‐5.4.24.tar.gz
cd php‐5.4.24
./configure ‐‐prefix=/usr/local/php5 ‐‐with‐mysql=/usr/local/mysql ‐‐enable‐fpm ‐‐
enable‐mbstring ‐‐with‐mcrypt ‐‐with‐mhash ‐‐with‐config‐file‐path=/usr/local/php5/etc ‐‐with‐
mysqli=/usr/local/mysql/bin/mysql_config
make && make install
/bin/cp -f php.ini‐production /usr/local/php5/etc/php.ini
/bin/cp -f /usr/local/php5/etc/php‐fpm.conf.default /usr/local/php5/etc/php‐fpm.conf
cd ..
else
echo "没有 php 源码包文件"
exit
fi
}
while :
do
menu
choice
case $select in
1)
install_nginx
;;
2)
install_mysql
;;
3)
install_php
;;
4)
exit
;;
*)
echo Sorry!
esac
done

52点名器脚本

#!/bin/bash
# 编写一个点名器脚本
# 该脚本,需要提前准备一个 user.txt 文件
# 该文件中需要包含所有姓名的信息,一行一个姓名,脚本每次随机显示一个姓名
while :
do
#统计 user 文件中有多少用户
line=`cat user.txt |wc ‐l`
num=$[RANDOM%line+1]
sed -n "${num}p" user.txt
sleep 0.2
clear
done

53查看有多少远程的 IP 在连接本机

#!/bin/bash
# 查看有多少远程的 IP 在连接本机(不管是通过 ssh 还是 web 还是 ftp 都统计)
# 使用 netstat ‐atn 可以查看本机所有连接的状态,‐a 查看所有,
# -t仅显示 tcp 连接的信息,‐n 数字格式显示
# Local Address(第四列是本机的 IP 和端口信息)
# Foreign Address(第五列是远程主机的 IP 和端口信息)
# 使用 awk 命令仅显示第 5 列数据,再显示第 1 列 IP 地址的信息
# sort 可以按数字大小排序,最后使用 uniq 将多余重复的删除,并统计重复的次数
netstat -atn | awk '{print $5}' | awk '{print $1}' | sort -nr | uniq -c

54对 100 以内的所有正整数相加求和(1+2+3+4…+100)

#!/bin/bash
# 对 100 以内的所有正整数相加求和(1+2+3+4...+100)
#seq 100 可以快速自动生成 100 个整数
sum=0
for i in `seq 100`
do
sum=$[sum+i]
done
echo "总和是:$sum"

55统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个

#!/bin/bash
# 统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个
# awk 使用‐F 选项指定文件内容的分隔符是/或者:
# 条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30
# 最后使用 wc ‐l 统计这样的数据有多少行,即多少个
awk -F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"' /var/log/httpd/access_log |wc -l

56统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么

#!/bin/bash
# 统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么
# awk 使用‐F 选项指定文件内容的分隔符是/或者:
# 条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30
# 日志文档内容里面,第 1 列是远程主机的 IP 地址,使用 awk 单独显示第 1 列即可
awk -F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"{print $1}' /var/log/httpd/access_log

57. 统计每个远程 IP 访问了本机 apache 几次?

#!/bin/bash
# 统计每个远程 IP 访问了本机 apache 几次?
awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log

58统计当前 Linux 系统中可以登录计算机的账户有多少个

#!/bin/bash
# 统计当前 Linux 系统中可以登录计算机的账户有多少个
#方法 1:
grep "bash$" /etc/passwd | wc -l
#方法 2:
awk -f: '/bash$/{x++}end{print x}' /etc/passwd

59统计/var/log 有多少个文件,并显示这些文件名

#!/bin/bash
# 统计/var/log 有多少个文件,并显示这些文件名
# 使用 ls 递归显示所有,再判断是否为文件,如果是文件则计数器加 1
cd /var/log
sum=0
for i in `ls -r *`
do
if [ -f $i ];then
let sum++
echo "文件名:$i"
fi
done
echo "总文件数量为:$sum"

60自动为其他脚本添加解释器信息

#!/bin/bash
# 自动为其他脚本添加解释器信息#!/bin/bash,如脚本名为 test.sh 则效果如下:
# ./test.sh abc.sh  自动为 abc.sh 添加解释器信息
# ./test.sh user.sh 自动为 user.sh 添加解释器信息
# 先使用 grep 判断对象脚本是否已经有解释器信息,如果没有则使用 sed 添加解释器以及描述信息
if ! grep -q "^#!" $1; then
sed '1i #!/bin/bash' $1
sed '2i #Description: '
fi
# 因为每个脚本的功能不同,作用不同,所以在给对象脚本添加完解释器信息,
# 以及 Description 后还希望继续编辑具体的脚本功能的描述信息,
# 这里直接使用 vim 把对象脚本打开,并且光标跳转到该文件的第 2 行
vim +2 $1

61编写 nginx 启动脚本

#!/bin/bash
# 编写 nginx 启动脚本
# 本脚本编写完成后,放置在/etc/init.d/目录下,就可以被 Linux 系统自动识别到该脚本
# 如果本脚本名为/etc/init.d/nginx,则 service nginx start 就可以启动该服务
# service nginx stop 就可以关闭服务
# service nginx restart 可以重启服务
# service nginx status 可以查看服务状态
program=/usr/local/nginx/sbin/nginx
pid=/usr/local/nginx/logs/nginx.pid
start(){
if [ -f $pid ];then
echo "nginx 服务已经处于开启状态"
else
$program
fi
stop(){
if [ -! -f $pid ];then
echo "nginx 服务已经关闭"
else
$program -s stop
echo "关闭服务 ok"
fi
}
status(){
if [ -f $pid ];then
echo "服务正在运行..."
else
echo "服务已经关闭"
fi
}
case $1 in
start)
start;;
stop)
stop;;
restart)
stop
sleep 1
start;;
status)
status;;
*)
echo "你输入的语法格式错误"
esac

62自动对磁盘分区、格式化、挂载

#!/bin/bash
# 自动对磁盘分区、格式化、挂载
# 对虚拟机的 vdb 磁盘进行分区格式化,使用<<将需要的分区指令导入给程序 fdisk
# n(新建分区),p(创建主分区),1(分区编号为 1),两个空白行(两个回车,相当于将整个磁盘分一个区)
# 注意:1 后面的两个回车(空白行)是必须的!
fdisk /dev/vdb << EOF
n
p
1
wq
EOF
#格式化刚刚创建好的分区
mkfs.xfs /dev/vdb1
#创建挂载点目录
if [ -e /data ]; then
exit
fi
mkdir /data
#自动挂载刚刚创建的分区,并设置开机自动挂载该分区
echo '/dev/vdb1 /data xfs defaults 1 2' >> /etc/fstab
mount -a

63自动优化 Linux 内核参数

#!/bin/bash
# 自动优化 Linux 内核参数
#脚本针对 RHEL7
cat >> /usr/lib/sysctl.d/00‐system.conf <<EOF
fs.file‐max=65535
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024 65535
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 5010 641280 5010 128
net.core.wmem_default=262144
net.core.wmem_max=262144
net.core.rmem_default=4194304
net.core.rmem_max=4194304
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
EOF
sysctl –p

64切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)

#mkdir /data/scripts
#vim /data/scripts/nginx_log.sh
#!/bin/bash
# 切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)
logs_path="/usr/local/nginx/logs/"
mv ${logs_path}access.log ${logs_path}access_$(date -d "yesterday" +"%Y%m%d").log
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
# chmod +x /data/scripts/nginx_log.sh
# crontab ‐e #脚本写完后,将脚本放入计划任务每天执行一次脚本
0 1 * * * /data/scripts/nginx_log.sh

65检测 MySQL 数据库连接数量

#!/bin/bash
# 检测 MySQL 数据库连接数量
# 本脚本每 2 秒检测一次 MySQL 并发连接数,可以将本脚本设置为开机启动脚本,或在特定时间段执行
# 以满足对 MySQL 数据库的监控需求,查看 MySQL 连接是否正常
# 本案例中的用户名和密码需要根据实际情况修改后方可使用
log_file=/var/log/mysql_count.log
user=root
passwd=123456
while :
do
sleep 2
count=`mysqladmin -u "$user" -p "$passwd" status | awk '{print $4}'`
echo "`date +%Y‐%m‐%d` 并发连接数为:$count" >> $log_file
done

66备份 MySQL 的 shell 脚本(mysqldump版本)

#!/bin/bash
# 备份 MySQL 的 shell 脚本(mysqldump版本)
# 定义变量 user(数据库用户名),passwd(数据库密码),date(备份的时间标签)
# dbname(需要备份的数据库名称,根据实际需求需要修改该变量的值,默认备份 mysql 数据库)
user=root
passwd=123456
dbname=mysql
date=$(date +%Y%m%d)
# 测试备份目录是否存在,不存在则自动创建该目录
[ ! -d /mysqlbackup ] && mkdir /mysqlbackup
# 使用 mysqldump 命令备份数据库
mysqldump -u "$user" -p "$passwd" "$dbname" > /mysqlbackup/"$dbname"-${date}.sql

67将文件中所有的小写字母转换为大写字母

#!/bin/bash
# 将文件中所有的小写字母转换为大写字母
# $1是位置参数,是你需要转换大小写字母的文件名称
# 执行脚本,给定一个文件名作为参数,脚本就会将该文件中所有的小写字母转换为大写字母
tr "[a‐z]" "[A‐Z]" < $1

68检查特定的软件包是否已经安装

#!/bin/bash
# 检查特定的软件包是否已经安装
if [ $# -eq 0 ];then
echo "你需要制定一个软件包名称作为脚本参数"
echo "用法:$0 软件包名称 ..."
fi
# $@提取所有的位置变量的值,相当于$*
for package in "$@"
do
if rpm -q ${package} &>/dev/null ;then
echo -e "${package}\033[32m 已经安装\033[0m"
else
echo -e "${package}\033[34;1m 未安装\033[0m"
fi
done

69监控 HTTP 服务器的状态(测试返回码)

#!/bin/bash
# 监控 HTTP 服务器的状态(测试返回码)
# 设置变量,url为你需要检测的目标网站的网址(IP 或域名),比如百度
url=http://http://183.232.231.172/index.html
# 定义函数 check_http:
# 使用 curl 命令检查 http 服务器的状态
# ‐m 设置curl不管访问成功或失败,最大消耗的时间为 5 秒,5 秒连接服务为相应则视为无法连接
# ‐s 设置静默连接,不显示连接时的连接速度、时间消耗等信息
# ‐o 将 curl 下载的页面内容导出到/dev/null(默认会在屏幕显示页面内容)
# ‐w 设置curl命令需要显示的内容%{http_code},指定curl返回服务器的状态码
check_http()
{
status_code=$(curl -m 5 -s -o /dev/null -w %{http_code} $url)
}
while :
do
check_http
date=$(date +%Y%m%d‐%H:%M:%S)
# 生成报警邮件的内容
echo "当前时间为:$date
$url 服务器异常,状态码为${status_code}.
请尽快排查异常." > /tmp/http$$.pid
# 指定测试服务器状态的函数,并根据返回码决定是发送邮件报警还是将正常信息写入日志
if [ $status_code -ne 200 ];then
mail -s Warning root < /tmp/http$$.pid
else
echo "$url 连接正常" >> /var/log/http.log
fi
sleep 5
done

70使用脚本自动创建逻辑卷

#!/bin/bash
# 使用脚本自动创建逻辑卷
# 清屏,显示警告信息,创建将磁盘转换为逻辑卷会删除数据
clear
echo -e "\033[32m !!!!!!警告(Warning)!!!!!!\033[0m"
echo
echo "+++++++++++++++++++++++++++++++++++++++++++++++++"
echo "脚本会将整个磁盘转换为 PV,并删除磁盘上所有数据!!!"
echo "This Script will destroy all data on the Disk"
echo "+++++++++++++++++++++++++++++++++++++++++++++++++"
echo
read -p "请问是否继续 y/n?:" sure
# 测试用户输入的是否为 y,如果不是则退出脚本
[ $sure != y ] && exit
# 提示用户输入相关参数(磁盘、卷组名称等数据),并测试用户是否输入了这些值,如果没有输入,则脚本退出
read -p "请输入磁盘名称,如/dev/vdb:" disk
[ -z $disk ] && echo "没有输入磁盘名称" && exit
read -p "请输入卷组名称:" vg_name
[ -z $vg_name ] && echo "没有输入卷组名称" && exit
read -p "请输入逻辑卷名称:" lv_name
[ -z $lv_name ] && echo "没有输入逻辑卷名称" && exit
read -p "请输入逻辑卷大小:" lv_size
[ -z $lv_size ] && echo "没有输入逻辑卷大小" && exit
# 使用命令创建逻辑卷
pvcreate $disk
vgcreate $vg_name $disk
lvcreate -L ${lv_size}M -n ${lv_name} ${vg_name}

71删除某个目录下大小为 0 的文件

#!/bin/bash
# 除某个目录下大小为 0 的文件
#/var/www/html 为测试目录,脚本会清空该目录下所有 0 字节的文件
dir="/var/www/html"
find $dir -type f -size 0 -exec rm -rf {} \;

72查找 Linux 系统中的僵尸进程

#!/bin/bash
# 查找 Linux 系统中的僵尸进程
# awk 判断 ps 命令输出的第 8 列为 Z 是,显示该进程的 PID 和进程命令
ps aux | awk '{if($8 == "Z"){print $2,$11}}'

73循环测试用户名与密码是否正确

#!/bin/bash
# 循环测试用户名与密码是否正确
# 循环测试用户的账户名和密码,最大测试 3 次,输入正确提示登录成功,否则提示登录失败
# 用户名为 tom 并且密码为 123456
for i in {1..3}
do
read -p "请输入用户名:" user
read -p "请输入密码:" pass
if [ "$user" == 'tom' -a "$pass" == '123456' ];then
echo "Login successful"
exit
fi
done
echo "Login Failed"

74显示当前计算机中所有账户的用户名称

#!/bin/bash
# 显示当前计算机中所有账户的用户名称
# 下面使用3种不同的方式列出计算机中所有账户的用户名
# 指定以:为分隔符,打印/etc/passwd 文件的第 1 列
awk -F: '{print $1}' /etc/passwd
# 指定以:为分隔符,打印/etc/passwd 文件的第 1 列
cut -d: -f1 /etc/passwd
# 使用 sed 的替换功能,将/etc/passwd 文件中:后面的所有内容替换为空(仅显示用户名)
sed 's/:.*//' /etc/passwd

75制定目录路径,脚本自动将该目录使用 tar 命令打包备份到/data目录

#!/bin/bash
# 制定目录路径,脚本自动将该目录使用 tar 命令打包备份到/data目录
[ ! -d /data ] && mkdir /data
[ -z $1 ] && exit
if [ -d $1 ];then
tar -czf /data/$1.-`date +%Y%m%d`.tar.gz $1
else
echo "该目录不存在"
fi

76安装 LAMP 环境(yum 版本)

#!/bin/bash
# 安装 LAMP 环境(yum 版本)
# 本脚本适用于 RHEL7(RHEL6 中数据库为 mysql)
yum makecache &>/dev/null
num=$(yum repolist | awk '/repolist/{print $2}' | sed 's/,//')
if [ $num -lt 0 ];then
yum -y install httpd
yum -y install mariadb mariadb-server mariadb-devel
yum -y install php php-mysql
else
echo "未配置 yum 源..."
fi

77获取本机 MAC 地址

#!/bin/bash
# 获取本机 MAC 地址
ip a s | awk 'BEGIN{print " 本 机 MAC 地 址 信 息 如 下 :"}/^[0‐9]/{print $2;getline;if($0~/link\/ether/){print $2}}' | grep -v lo:
# awk 读取 ip 命令的输出,输出结果中如果有以数字开始的行,先显示该行的地 2 列(网卡名称),
# 接着使用 getline 再读取它的下一行数据,判断是否包含 link/ether
# 如果保护该关键词,就显示该行的第 2 列(MAC 地址)
# lo 回环设备没有 MAC,因此将其屏蔽,不显示

78修改 Linux 系统的最大打开文件数量

#!/bin/bash
# 修改 Linux 系统的最大打开文件数量
# 往/etc/security/limits.conf 文件的末尾追加两行配置参数,修改最大打开文件数量为 65536
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65536
* hard nofile 65536
EOF

79统计 Linux 进程相关数量信息

#!/bin/bash
# 统计 Linux 进程相关数量信息
running=0
sleeping=0
stoped=0
zombie=0
# 在 proc 目录下所有以数字开始的都是当前计算机正在运行的进程的进程 PID
# 每个 PID 编号的目录下记录有该进程相关的信息
for pid in /proc/[1‐9]*
do
procs=$[procs+1]
stat=$(awk '{print $3}' $pid/stat)
# 每个 pid 目录下都有一个 stat 文件,该文件的第 3 列是该进程的状态信息
case $stat in
R)
running=$[running+1]
;;
T)
stoped=$[stoped+1]
;;
S)
sleeping=$[sleeping+1]
;;
Z)
zombie=$[zombie+1]
;;
esac
done
echo "进程统计信息如下"
echo "总进程数量为:$procs"
echo "Running 进程数为:$running"
echo "Stoped 进程数为:$stoped"
echo "Sleeping 进程数为:$sleeping"
echo "Zombie 进程数为:$zombie"

80显示本机 Linux 系统上所有开放的端口列表

#!/bin/bash
# 显示本机 Linux 系统上所有开放的端口列表
# 从端口列表中观测有没有没用的端口,有的话可以将该端口对应的服务关闭,防止意外的攻击可能性
ss -nutlp | awk '{print $1,$5}' | awk -F"[: ]" '{print "协议:"$1,"端口号:"$NF}' | grep "[0‐9]" | uniq

81将 Linux 系统中 UID 大于等于 1000 的普通用户都删除

#!/bin/bash
# 将 Linux 系统中 UID 大于等于 1000 的普通用户都删除
# 先用 awk 提取所有 uid 大于等于 1000 的普通用户名称
# 再使用 for 循环逐个将每个用户删除即可
user=$(awk -F: '$3>=1000{print $1}' /etc/passwd)
for i in $user
do
userdel -r $i
done

82,Shell脚本对Linux进行文件校验

一、需求

有客户等保需求对文件一致性进行校验,想到利用md5sum工具,因此写脚本来对文件进行自定义扫描,后期可以利用其进行校验,快速校验文件发现变更的文件,一定程度及时发现行为。

二、脚本

利用md5sum将扫描得到的文件保存在/tmp目录下,后缀为时间戳,后期可以利用此文件进行校验

#!/bin/bash
#func:scan file
#md5sum -c $SCAN_FILESCAN_DIR=`echo $PATH |sed 's/:/ /g'`
SCAN_CMD=`which md5sum`
SCAN_FILE_FAIL="/tmp/scan_$(date +%F%H%m)_fall.txt"
SCAN_FILE_BIN="/tmp/scan_$(date +%F%H%m)_bin.txt"scan_fall_disk() {echo "正在全盘扫描,请稍等!文件路径:$SCAN_FILE_FALL"find / -type f ! -path "/proc/*" -exec $SCAN_CMD \{\} \;>> $SCAN_FILE_FAIL 2>/dev/nullecho "扫描完成,可利用以下命令后期对文件进行校验"echo "$SCAN_CMD -c $SCAN_FILE_FAIL |grep -v 'OK$'"
}scan_bin() {echo "正在扫描$PATH可执行文件,请稍等,文件路径:$SCAN_FILE_BIN"for file in $SCAN_DIRdofind $file -type f -exec $SCAN_CMD \{\} \;>> $SCAN_FILE_BIN 2>/dev/nulldoneecho "扫描完成,可利用以下命令后期对文件进行校验"echo "$SCAN_CMD -c $SCAN_FILE_BIN |grep -v 'OK$'"
}clear
echo "##########################################"
echo "#                                                                                #"
echo "#        利用md5sum对文件进行校验                          #"
echo "#                                                                                #"
echo "##########################################"
echo "1: 全盘扫描"
echo "2: bin path扫描"
echo "3: EXIT"
# 选择扫描方式
read -p "Please input your choice:" method
case $method in
1)scan_fall_disk;;
2)scan_bin;;
3)echo "you choce channel!" && exit 1;;
*)echo "input Error! Place input{1|2|3}" && exit 0;;
esac

三、测试

  • 扫描二进制可执行文件 由于可执行文件异常敏感,如果系统可能有将自己的程序放在可行性路径下,或替换原有二进制文件,对

    $PATH
    

    目录进行扫描

    将wc 文件移动到其他路径,或按照其他程序,二进制文件有变化就可以检测出来

  • 全盘扫描

俄罗斯方块

#!/bin/bashAPP_NAME="${0##*[\\/]}"
APP_VERSION="1.0"#颜色定义
iSumColor=7         #颜色总数
cRed=1              #红色
cGreen=2            #绿色
cYellow=3           #×××
cBlue=4             #蓝色
cFuchsia=5          #紫红色
cCyan=6             #青色(蓝绿色)
cWhite=7            #白色#位置与大小
marginLeft=3            #边框左边距
marginTop=2         #边框上边距
((mapLeft=marginLeft+2))    #棋盘左边距
((mapTop=$marginTop+1))     #棋盘上边距
mapWidth=10         #棋盘宽度
mapHeight=15            #棋盘高度#颜色设置
cBorder=$cGreen
cScore=$cFuchsia
cScoreValue=$cCyan#控制信号
#游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面;
#当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。
sigRotate=25        #向上键
sigLeft=26
sigRight=27
sigDown=28
sigAllDown=29       #空格键
sigExit=30#方块定义,7大类19种样式
#前8位为方块坐标,后2位为方块刚出现的时候的位置
box0_0=(0 0 0 1 1 0 1 1 0 4)box1_0=(0 1 1 1 2 1 3 1 0 3)
box1_1=(1 0 1 1 1 2 1 3 -1 3)box2_0=(0 0 1 0 1 1 2 1 0 4)
box2_1=(0 1 0 2 1 0 1 1 0 3)box3_0=(0 1 1 0 1 1 2 0 0 4)
box3_1=(0 0 0 1 1 1 1 2 0 4)box4_0=(0 2 1 0 1 1 1 2 0 3)
box4_1=(0 1 1 1 2 1 2 2 0 3)
box4_2=(1 0 1 1 1 2 2 0 -1 3)
box4_3=(0 0 0 1 1 1 2 1 0 4)box5_0=(0 0 1 0 1 1 1 2 0 3)
box5_1=(0 1 0 2 1 1 2 1 0 3)
box5_2=(1 0 1 1 1 2 2 2 -1 3)
box5_3=(0 1 1 1 2 0 2 1 0 4)box6_0=(0 1 1 0 1 1 1 2 0 3)
box6_1=(0 1 1 1 1 2 2 1 0 3)
box6_2=(1 0 1 1 1 2 2 1 -1 3)
box6_3=(0 1 1 0 1 1 2 1 0 4)iSumType=7          #方块类型总数
boxStyle=(1 2 2 2 4 4 4)    #各种方块旋转后可能的样式数目iScoreEachLevel=50  #提升一个级别需要的分数
#运行时数据
sig=0           #接收到的signal
iScore=0        #总分
iLevel=0        #速度级
boxNext=()      #下一个方块
iboxNextColor=0     #下一个方块的颜色
iboxNextType=0      #下一个方块的种类
iboxNextStyle=0     #下一个方块的样式
boxCur=()       #当前方块的位置定义
iBoxCurColor=0      #当前方块的颜色
iBoxCurType=0       #当前方块的种类
iBoxCurStyle=0      #当前方块的样式
boxCurX=-1      #当前方块的x坐标位置
boxCurY=-1      #当前方块的y坐标位置
map=()          #棋盘图表#初始化所有背景方块为-1, 表示没有方块
for ((i = 0; i < mapHeight * mapWidth; i++))
domap[$i]=-1
done#接收输入的进程的主函数
function RunAsKeyReceiver()
{local pidDisplayer key aKey sig cESC sTTYpidDisplayer=$1aKey=(0 0 0)cESC=`echo -ne "\033"`cSpace=`echo -ne "\040"`#保存终端属性。在read -s读取终端键时,终端的属性会被暂时改变。#如果在read -s时程序被不幸杀掉,可能会导致终端混乱,#需要在程序退出时恢复终端属性。sTTY=`stty -g`#捕捉退出信号trap "MyExit;" INT QUITtrap "MyExitNoSub;" $sigExit#隐藏光标echo -ne "\033[?25l"while :do#读取输入。注-s不回显,-n读到一个字符立即返回read -s -n 1 keyaKey[0]=${aKey[1]}aKey[1]=${aKey[2]}aKey[2]=$keysig=0#判断输入了何种键if [[ $key == $cESC && ${aKey[1]} == $cESC ]]then#ESC键MyExitelif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]thenif [[ $key == "A" ]]; then sig=$sigRotate   #<向上键>elif [[ $key == "B" ]]; then sig=$sigDown   #<向下键>elif [[ $key == "D" ]]; then sig=$sigLeft   #<向左键>elif [[ $key == "C" ]]; then sig=$sigRight  #<向右键>fielif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate  #W, welif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown    #S, selif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft    #A, aelif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight   #D, delif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown   #空格键elif [[ $key == "Q" || $key == "q" ]]           #Q, qthenMyExitfiif [[ $sig != 0 ]]then#向另一进程发送消息kill -$sig $pidDisplayerfidone
}#退出前的恢复
MyExitNoSub()
{local y#恢复终端属性stty $sTTY((y = marginTop + mapHeight + 4))#显示光标echo -e "\033[?25h\033[${y};0H"exit
}MyExit()
{#通知显示进程需要退出kill -$sigExit $pidDisplayerMyExitNoSub
}#处理显示和游戏流程的主函数
RunAsDisplayer()
{local sigThisInitDraw#挂载各种信号的处理函数trap "sig=$sigRotate;" $sigRotatetrap "sig=$sigLeft;" $sigLefttrap "sig=$sigRight;" $sigRighttrap "sig=$sigDown;" $sigDowntrap "sig=$sigAllDown;" $sigAllDowntrap "ShowExit;" $sigExitwhile :do#根据当前的速度级iLevel不同,设定相应的循环的次数for ((i = 0; i < 21 - iLevel; i++))dosleep 0.02sigThis=$sigsig=0#根据sig变量判断是否接受到相应的信号if ((sigThis == sigRotate)); then BoxRotate;    #旋转elif ((sigThis == sigLeft)); then BoxLeft;  #左移一列elif ((sigThis == sigRight)); then BoxRight;    #右移一列elif ((sigThis == sigDown)); then BoxDown;  #下落一行elif ((sigThis == sigAllDown)); then BoxAllDown;    #下落到底fidone#kill -$sigDown $$BoxDown #下落一行done
}#绘制当前方块,传第一个参数,0表示擦除当前方块,1表示绘制当前方块
DrawCurBox()
{local i x y bErase sBoxbErase=$1if (( bErase == 0 ))thensBox="\040\040"     #用两个空格擦除elsesBox="[]"echo -ne "\033[1m\033[3${iBoxCurColor}m\033[4${iBoxCurColor}m"fifor ((i = 0; i < 8; i += 2))do((y = mapTop + 1 + ${boxCur[$i]} + boxCurY))((x = mapLeft + 1 + 2 * (boxCurX + ${boxCur[$i + 1]})))echo -ne "\033[${y};${x}H${sBox}"doneecho -ne "\033[0m"
}#移动方块
#BoxMove(y, x), 测试是否可以把移动中的方块移到(y, x)的位置, 返回0则可以, 1不可以
BoxMove()
{local i x y xPos yPosyPos=$1xPos=$2for ((i = 0; i < 8; i += 2))do#方块相对于棋盘坐标((y = yPos + ${boxCur[$i]}))((x = xPos + ${boxCur[$i + 1]}))if (( y < 0 || y >= mapHeight || x < 0 || x >= mapWidth))then#撞到墙壁了return 1fiif (( ${map[y * mapWidth + x]} != -1 ))then#撞到其他已经存在的方块了return 1fidonereturn 0;
}#将方块贴到棋盘上
Box2Map()
{local i j x y line#将当前移动中的方块贴到棋盘对应的区域for ((i = 0; i < 8; i += 2))do#计算方块相对于棋盘的坐标((y = ${boxCur[$i]} + boxCurY))((x = ${boxCur[$i + 1]} + boxCurX))map[y*mapWidth+x]=$iBoxCurColor #将方块颜色赋给地图doneline=0for ((i = 0; i < mapHeight; i++))dofor ((j = 0; j < mapWidth; j++))do#如果棋盘上有空隙,跳出循环[[ ${map[i*mapWidth+j]} -eq -1 ]] && breakdone[ $j -lt $mapWidth ] && continue#说明当前行可消去,可消去行数加一(( line++ ))#第i行可被消除,将0行至第i-1行全部下移一行,从第i-1行开始移动for ((j = i*mapWidth-1; j >= 0; j--))do((x = j + mapWidth))map[$x]=${map[$j]}done#因为下移一行,第0行置空for ((i = 0; i < mapWidth; i++))domap[$i]=-1donedone[ $line -eq 0 ] && return#根据消去的行数line计算分数和速度级((x = marginLeft + mapWidth * 2 + 7))((y = marginTop + 11))((iScore += line * 2 - 1))#显示新的分数echo -ne "\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore}         "if ((iScore % iScoreEachLevel < line * 2 - 1))thenif ((iLevel < 20))then((iLevel++))((y = marginTop + 14))#显示新的速度级echo -ne "\033[3${cScoreValue}m\033[${y};${x}H${iLevel}        "fifiecho -ne "\033[0m"#重新显示背景方块for ((i = 0; i < mapHeight; i++))do#棋盘相对于屏幕的坐标((y = i + mapTop + 1))((x = mapLeft + 1))echo -ne "\033[${y};${x}H"for ((j = 0; j < mapWidth; j++))do((tmp = i * mapWidth + j))if ((${map[$tmp]} == -1))thenecho -ne "  "elseecho -ne "\033[1m\033[3${map[$tmp]}m\033[4${map[$tmp]}m[]\033[0m"fidonedone
}#左移一格
BoxLeft()
{local x((x = boxCurX - 1))if BoxMove $boxCurY $xthenDrawCurBox 0((boxCurX = x))DrawCurBox 1fi
}#右移一格
BoxRight()
{local x((x = boxCurX + 1))if BoxMove $boxCurY $xthenDrawCurBox 0((boxCurX = x))DrawCurBox 1fi
}#向下移一格
BoxDown()
{local y((y = boxCurY + 1)) #新的y坐标if BoxMove $y $boxCurX  #测试是否可以下落一行thenDrawCurBox 0    #将旧的方块抹去((boxCurY = y))DrawCurBox 1    #显示新的下落后方块else#走到这儿, 如果不能下落了Box2Map     #将当前移动中的方块贴到背景方块中CreateBox   #产生新的方块fi
}#下落到底
BoxAllDown()
{local y iDown#计算能够下落的行数iDown=0(( y = boxCurY + 1 ))while BoxMove $y $boxCurXdo(( y++ ))(( iDown++ ))doneDrawCurBox 0    #将旧的方块抹去((boxCurY += iDown))DrawCurBox 1    #显示新的下落后的方块Box2Map     #将当前移动中的方块贴到背景方块中CreateBox   #产生新的方块
}#翻转
BoxRotate()
{[ ${boxStyle[$iBoxCurType]} -eq 1 ] && return((rotateStyle = (iBoxCurStyle + 1) % ${boxStyle[$iBoxCurType]}))#将当前方块保存到boxTmpboxTmp=( `eval 'echo ${boxCur[@]}'` )boxCur=( `eval 'echo ${box'$iBoxCurType'_'$rotateStyle'[@]}'` )if BoxMove $boxCurY $boxCurX    #测试旋转后是否有空间放的下then#抹去旧的方块boxCur=( `eval 'echo ${boxTmp[@]}'` )DrawCurBox 0boxCur=( `eval 'echo ${box'$iBoxCurType'_'$rotateStyle'[@]}'` )DrawCurBox 1iBoxCurStyle=$rotateStyleelse#不能旋转,还是继续使用老的样式boxCur=( `eval 'echo ${boxTmp[@]}'` )fi
}#准备下一个方块
PrepareNextBox()
{local i x y#清除右边预显示的方块if (( ${#boxNext[@]} != 0 )); thenfor ((i = 0; i < 8; i += 2))do((y = marginTop + 1 + ${boxNext[$i]}))((x = marginLeft + 2 * mapWidth + 7 + 2 * ${boxNext[$i + 1]}))echo -ne "\033[${y};${x}H\040\040"donefi#随机生成预显式方块(( iBoxNextType = RANDOM % iSumType ))(( iBoxNextStyle = RANDOM % ${boxStyle[$iBoxNextType]} ))(( iBoxNextColor = RANDOM % $iSumColor + 1 ))boxNext=( `eval 'echo ${box'$iBoxNextType'_'$iBoxNextStyle'[@]}'` )#显示右边预显示的方块echo -ne "\033[1m\033[3${iBoxNextColor}m\033[4${iBoxNextColor}m"for ((i = 0; i < 8; i += 2))do((y = marginTop + 1 + ${boxNext[$i]}))((x = marginLeft + 2 * mapWidth + 7 + 2 * ${boxNext[$i + 1]}))echo -ne "\033[${y};${x}H[]"doneecho -ne "\033[0m"}#显示新方块
CreateBox()
{if (( ${#boxCur[@]} == 0 )); then#当前方块不存在(( iBoxCurType = RANDOM % iSumType ))(( iBoxCurStyle = RANDOM % ${boxStyle[$iBoxCurType]} ))(( iBoxCurColor = RANDOM % $iSumColor + 1 ))else#当前方块已存在, 将下一个方块赋给当前方块iBoxCurType=$iBoxNextType;iBoxCurStyle=$iBoxNextStyle;iBoxCurColor=$iBoxNextColorfi#当前方块数组boxCur=( `eval 'echo ${box'$iBoxCurType'_'$iBoxCurStyle'[@]}'` )#初始化方块起始坐标boxCurY=boxCur[8];boxCurX=boxCur[9];DrawCurBox 1        #绘制当前方块if ! BoxMove $boxCurY $boxCurXthenkill -$sigExit $PPIDShowExitfiPrepareNextBox}#绘制边框
DrawBorder()
{clearlocal i y x1 x2#显示边框echo -ne "\033[1m\033[3${cBorder}m\033[4${cBorder}m"((x1 = marginLeft + 1))             #左边框x坐标((x2 = x1 + 2 + mapWidth * 2))          #右边框x坐标for ((i = 0; i < mapHeight; i++))do((y = i + marginTop + 2))echo -ne "\033[${y};${x1}H||"       #绘制左边框echo -ne "\033[${y};${x2}H||"       #绘制右边框done((x1 = marginTop + mapHeight + 2))for ((i = 0; i < mapWidth + 2; i++))do((y = i * 2 + marginLeft + 1))echo -ne "\033[${mapTop};${y}H=="   #绘制上边框echo -ne "\033[${x1};${y}H=="       #绘制下边框doneecho -ne "\033[0m"#显示"Score"和"Level"字样echo -ne "\033[1m"((y = marginLeft + mapWidth * 2 + 7))((x1 = marginTop + 10))echo -ne "\033[3${cScore}m\033[${x1};${y}HScore"((x1 = marginTop + 11))echo -ne "\033[3${cScoreValue}m\033[${x1};${y}H${iScore}"((x1 = marginTop + 13))echo -ne "\033[3${cScore}m\033[${x1};${y}HLevel"((x1 = marginTop + 14))echo -ne "\033[3${cScoreValue}m\033[${x1};${y}H${iLevel}"echo -ne "\033[0m"
}InitDraw()
{clear           #清屏DrawBorder      #绘制边框CreateBox       #创建方块
}#退出时显示GameOVer!
ShowExit()
{local y((y = mapHeight + mapTop + 3))echo -e "\033[${y};1HGameOver!\033[0m"exit
}#游戏主程序在这儿开始.
if [[ "$1" == "--version" ]]; thenecho "$APP_NAME $APP_VERSION"
elif [[ "$1" == "--show" ]]; then#当发现具有参数--show时,运行显示函数RunAsDisplayer
elsebash $0 --show& #以参数--show将本程序再运行一遍RunAsKeyReceiver $! #以上一行产生的进程的进程号作为参数
fikeytest.sh#!/bin/bashGetKey()
{aKey=(0 0 0) #定义一个数组来保存3个按键cESC=`echo -ne "\033"`cSpace=`echo -ne "\040"`while :doread -s -n 1 key  #读取一个字符,将读取到的字符保存在key中#echo $key#echo XXX aKey[0]=${aKey[1]} #第一个按键aKey[1]=${aKey[2]} #第二个按键aKey[2]=$key        #第三个按键if [[ $key == $cESC && ${aKey[1]} == $cESC ]]thenMyExitelif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]thenif [[ $key == "A" ]]; then echo KEYUPelif [[ $key == "B" ]]; then echo KEYDOWNelif [[ $key == "D" ]]; then echo KEYLEFTelif [[ $key == "C" ]]; then echo KEYRIGHTfifidone
}GetKeydraw.sh#!/bin/bash#位置与大小
marginLeft=8            #边框左边距
marginTop=6         #边框上边距
((mapLeft=marginLeft+2))    #棋盘左边距
((mapTop=$marginTop+1))     #棋盘上边距
mapWidth=10         #棋盘宽度
mapHeight=15            #棋盘高度#方块定义,7大类19种样式
#前8位为方块坐标,后2位为方块刚出现的时候的位置
box0_0=(0 0 0 1 1 0 1 1 0 4)box1_0=(0 1 1 1 2 1 3 1 0 3)
box1_1=(1 0 1 1 1 2 1 3 -1 3)box2_0=(0 0 1 0 1 1 2 1 0 4)
box2_1=(0 1 0 2 1 0 1 1 0 3)box3_0=(0 1 1 0 1 1 2 0 0 4)
box3_1=(0 0 0 1 1 1 1 2 0 4)box4_0=(0 2 1 0 1 1 1 2 0 3)
box4_1=(0 1 1 1 2 1 2 2 0 3)
box4_2=(1 0 1 1 1 2 2 0 -1 3)
box4_3=(0 0 0 1 1 1 2 1 0 4)box5_0=(0 0 1 0 1 1 1 2 0 3)
box5_1=(0 1 0 2 1 1 2 1 0 3)
box5_2=(1 0 1 1 1 2 2 2 -1 3)
box5_3=(0 1 1 1 2 0 2 1 0 4)box6_0=(0 1 1 0 1 1 1 2 0 3)
box6_1=(0 1 1 1 1 2 2 1 0 3)
box6_2=(1 0 1 1 1 2 2 1 -1 3)
box6_3=(0 1 1 0 1 1 2 1 0 4)#绘制边框
DrawBorder()
{clearlocal i y x1 x2#显示边框echo -ne "\033[1m\033[32m\033[42m"((x1 = marginLeft + 1))             #左边框x坐标((x2 = x1 + 2 + mapWidth * 2))          #右边框x坐标for ((i = 0; i < mapHeight; i++))do((y = i + marginTop + 2))echo -ne "\033[${y};${x1}H||"       #绘制左边框echo -ne "\033[${y};${x2}H||"       #绘制右边框done((x1 = marginTop + mapHeight + 2))for ((i = 0; i < mapWidth + 2; i++))do((y = i * 2 + marginLeft + 1))echo -ne "\033[${mapTop};${y}H=="   #绘制上边框echo -ne "\033[${x1};${y}H=="       #绘制下边框doneecho -ne "\033[0m"
}DrawBox()
{local i x y xPos yPosyPos=${box0_0[8]}xPos=${box0_0[9]}echo -ne "\033[1m\033[35m\033[45m"for ((i = 0; i < 8; i += 2))do(( y = mapTop + 1 + ${box0_0[$i]} + yPos ))(( x = mapLeft + 1 + 2 * (${box0_0[$i + 1]} + xPos) ))echo -ne "\033[${y};${x}H[]"doneecho -ne "\033[0m"
}InitDraw()
{clear           #清屏DrawBorder      #绘制边框DrawBoxwhile :dosleep 1done
}

shell脚本练习2023年下岗版相关推荐

  1. Linux命令行与shell脚本编程大全:第2版

    <Linux命令行与shell脚本编程大全:第2版> 基本信息 作者: (美)布卢姆(Blum,R.) 布雷斯纳汉(Bresnahan.C.) [作译者介绍] 译者: 武海峰 丛书名: 图 ...

  2. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---34

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  3. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---02

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  4. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---20

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  5. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---43

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  6. 《Linux命令行与shell脚本编程大全 第3版》高级Shell脚本编程---32

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  7. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---10

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  8. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---23

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  9. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---55

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

最新文章

  1. Transform组件C#游戏开发快速入门
  2. .net源代码已经可以调试
  3. python爬虫——论抓包的正确姿势和学好Javascript的重要性(1)
  4. asset文件夹路径 unity_Unity Assets目录下的特殊文件夹名称
  5. Bailian2697 迭代法解方程【二分+迭代】
  6. networkxpdf_1 NetworkX概述
  7. 在鼠标右键菜单栏添加notepad++打开方式
  8. 算法:匹配有效的括号20. Valid Parentheses
  9. 软件无线电 多核服务器,软件无线电 SDR LTE平台简介
  10. QTreeView设置branch图标大小
  11. java-序列化以及反序列化
  12. hdmi接口和计算机连接,hdmi接口,教您hdmi接口怎么连接电视
  13. python的三种基本结构流程图_程序的三种基本结构是什么
  14. 家庭局域网接入Internet
  15. 使用springboot+vue+element-ui模仿蓝墨云班课
  16. 查看创建数据库的sql语句
  17. 硬件知识:台式电脑主机各种接口介绍
  18. 云机器被渗透了怎么办以及解决方法!
  19. 酷派大观4 8970 刷android 4.4,极速达百兆! 移动4G版酷派大观4网络体验
  20. Flink 使用Table Api 读取文件数据并写出到文件中

热门文章

  1. 蓝牙WiFi 智能手机无线打印全攻略
  2. 安川伺服驱动器usb驱动_不受信任的USB驱动器有哪些危害?
  3. 酒店客房住宿预定管理系统(ssm,mysql)
  4. 投了上千简历,是Android岗位需求少?还是我的技术不行
  5. HTC G11图案解锁
  6. android,java判断密码强度
  7. 国产的工业Rfid有哪些品牌
  8. linux opengl es,在Linux上,如何开发OpenGL ES(GLES)2.0应用程序?
  9. Onedrive服务器位置,私享空间-OneDrive:同步目录不要在C盘
  10. iOS App 百思不得姐