bash

用bash shell写程序时,经常会用到for循环,特别是从1到100这种需求,这里记录几种shell中从1到100的循环方法

方法
类c语言
for ((i=1; i<=100; i ++))
do
	echo $i
done


in使用
for i in {1..100}
do
	echo $i
done

seq使用
作用
seq - print a sequence of numbers

代码
for i in `seq 1 100`
do
	echo $i
done

30个经典shell
1、获取随机字符串或数字
获取随机8位字符串:

方法1:

 echo $RANDOM |md5sum |cut -c 1-8
471b94f2

方法2:

 openssl rand -base64 4
vg3BEg==

方法3:

 cat /proc/sys/kernel/random/uuid |cut -c 1-8
ed9e032c

获取随机8位数字:

方法1:

 echo $RANDOM |cksum |cut -c 1-8
23648321

方法2:

 openssl rand -base64 4 |cksum |cut -c 1-8
38571131

方法3:

 date +%N |cut -c 1-8
69024815

cksum:打印CRC效验和统计字节

2、定义一个颜色输出字符串函数
方法1:

function echo_color() {

    if [ $1 == "green" ]; then

        echo -e "33[32;40m$233[0m"

    elif [ $1 == "red" ]; then

        echo -e "33[31;40m$233[0m"

    fi

}

方法2:

function echo_color() {

    case $1 in

        green)

            echo -e "[32;40m$2[0m"

            ;;

        red)

            echo -e "[31;40m$2[0m" 

            ;;

        *) 

            echo "Example: echo_color red string"

    esac

}

使用方法:echo_color green "test"

function关键字定义一个函数,可加或不加。

3、批量创建用户
!/bin/bash
DATE=$(date +%F_%T)

USER_FILE=user.txt

echo_color(){

    if [ $1 == "green" ]; then

        echo -e "[32;40m$2[0m"

    elif [ $1 == "red" ]; then

        echo -e "[31;40m$2[0m"

    fi

}

 如果用户文件存在并且大小大于0就备份
if [ -s $USER_FILE ]; then

    mv $USER_FILE ${USER_FILE}-${DATE}.bak

    echo_color green "$USER_FILE exist, rename ${USER_FILE}-${DATE}.bak"

fi

echo -e "User Password" >> $USER_FILE

echo "----------------" >> $USER_FILE

for USER in user{1..10}; do

    if ! id $USER &>/dev/null; then

        PASS=$(echo $RANDOM |md5sum |cut -c 1-8)

        useradd $USER

        echo $PASS |passwd --stdin $USER &>/dev/null

        echo -e "$USER $PASS" >> $USER_FILE

        echo "$USER User create successful."

    else

        echo_color red "$USER User already exists!"

    fi

done

 
4、检查软件包是否安装
!/bin/bash
if rpm -q sysstat &>/dev/null; then

    echo "sysstat is already installed."

else

    echo "sysstat is not installed!"

fi

 
5、检查服务状态
!/bin/bash
PORT_C=$(ss -anu |grep -c 123)

PS_C=$(ps -ef |grep ntpd |grep -vc grep)

if [ $PORT_C -eq 0 -o $PS_C -eq 0 ]; then

    echo "内容" | mail -s "主题" dst@example.com

fi

****
6、检查主机存活状态
方法1:将错误IP放到数组里面判断是否ping失败三次

!/bin/bash  
IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2"

for IP in $IP_LIST; do

    NUM=1

    while [ $NUM -le 3 ]; do

        if ping -c 1 $IP > /dev/null; then

            echo "$IP Ping is successful."

            break

        else

            # echo "$IP Ping is failure $NUM"

            FAIL_COUNT[$NUM]=$IP

            let NUM++

        fi

    done

    if [ ${#FAIL_COUNT[]} -eq 3 ];then

        echo "${FAIL_COUNT[1]} Ping is failure!"

        unset FAIL_COUNT[]

    fi

done

方法2:将错误次数放到FAIL_COUNT变量里面判断是否ping失败三次

!/bin/bash  
IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2"

for IP in $IP_LIST; do

    FAIL_COUNT=0

    for ((i=1;i<=3;i++)); do

        if ping -c 1 $IP >/dev/null; then

            echo "$IP Ping is successful."

            break

        else

            # echo "$IP Ping is failure $i"

            let FAIL_COUNT++

        fi

    done

    if [ $FAIL_COUNT -eq 3 ]; then

        echo "$IP Ping is failure!"

    fi

done

方法3:利用for循环将ping通就跳出循环继续,如果不跳出就会走到打印ping失败

!/bin/bash
ping_success_status() {

    if ping -c 1 $IP >/dev/null; then

        echo "$IP Ping is successful."

        continue

    fi

}

IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2"

for IP in $IP_LIST; do

    ping_success_status

    ping_success_status

    ping_success_status

    echo "$IP Ping is failure!"

done

****
7、监控CPU、内存和硬盘利用率
1)CPU

借助vmstat工具来分析CPU统计信息。

!/bin/bash
DATE=$(date +%F" "%H:%M)

IP=$(ifconfig eth0 |awk -F  [ :]+   /inet addr/{print $4} )  # 只支持CentOS6

MAIL="example@mail.com"

if ! which vmstat &>/dev/null; then

    echo "vmstat command no found, Please install procps package." 

    exit 1

fi

US=$(vmstat |awk  NR==3{print $13} )

SY=$(vmstat |awk  NR==3{print $14} )

IDLE=$(vmstat |awk  NR==3{print $15} )

WAIT=$(vmstat |awk  NR==3{print $16} )

USE=$(($US+$SY))

if [ $USE -ge 50 ]; then

    echo "

    Date: $DATE

    Host: $IP

    Problem: CPU utilization $USE

    " | mail -s "CPU Monitor" $MAIL

fi

2)内存

!/bin/bash
DATE=$(date +%F" "%H:%M)

IP=$(ifconfig eth0 |awk -F  [ :]+   /inet addr/{print $4} )  

MAIL="example@mail.com"

TOTAL=$(free -m |awk  /Mem/{print $2} )

USE=$(free -m |awk  /Mem/{print $3-$6-$7} )

FREE=$(($TOTAL-$USE))

 内存小于1G发送报警邮件
if [ $FREE -lt 1024 ]; then

    echo "

    Date: $DATE

    Host: $IP

    Problem: Total=$TOTAL,Use=$USE,Free=$FREE

    " | mail -s "Memory Monitor" $MAIL

fi

3)硬盘

!/bin/bash
DATE=$(date +%F" "%H:%M)

IP=$(ifconfig eth0 |awk -F  [ :]+   /inet addr/{print $4} )  

MAIL="example@mail.com"

TOTAL=$(fdisk -l |awk -F [: ]+   BEGIN{OFS="="}/^Disk /dev/{printf "%s=%sG,",$2,$3} )

PART_USE=$(df -h |awk  BEGIN{OFS="="}/^/dev/{print $1,int($5),$6} )

for i in $PART_USE; do

    PART=$(echo $i |cut -d"=" -f1)

    USE=$(echo $i |cut -d"=" -f2)

    MOUNT=$(echo $i |cut -d"=" -f3)

    if [ $USE -gt 80 ]; then

        echo "

        Date: $DATE

        Host: $IP

        Total: $TOTAL

        Problem: $PART=$USE($MOUNT)

        " | mail -s "Disk Monitor" $MAIL

    fi

done

****
8、批量主机磁盘利用率监控
前提监控端和被监控端SSH免交互登录或者密钥登录。

写一个配置文件保存被监控主机SSH连接信息,文件内容格式:IP User Port

!/bin/bash
HOST_INFO=host.info

for IP in $(awk  /^[^#]/{print $1}  $HOST_INFO); do

    USER=$(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.tmp

    ssh -p $PORT $USER@$IP  df -h  > $TMP_FILE

    USE_RATE_LIST=$(awk  BEGIN{OFS="="}/^/dev/{print $1,int($5)}  $TMP_FILE)

    for USE_RATE in $USE_RATE_LIST; do

        PART_NAME=${USE_RATE%=}

        USE_RATE=${USE_RATE#=}

        if [ $USE_RATE -ge 80 ]; then

            echo "Warning: $PART_NAME Partition usage $USE_RATE%!"

        fi

    done

done

****
9、检查网站可用性
1)检查URL可用性

方法1:

check_url() {

    HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $1)

    if [ $HTTP_CODE -ne 200 ]; then

        echo "Warning: $1 Access failure!"

    fi

}

方法2:

check_url() {

if ! wget -T 10 --tries=1 --spider $1 >/dev/null 2>&1; then  

-T超时时间,--tries尝试1次,--spider爬虫模式
        echo "Warning: $1 Access failure!"

    fi

}

使用方法:check_url www.baidu.com

2)判断三次URL可用性

思路与上面检查主机存活状态一样。

方法1:利用循环技巧,如果成功就跳出当前循环,否则执行到最后一行

!/bin/bash  
check_url() {

    HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $1)

    if [ $HTTP_CODE -eq 200 ]; then

        continue

    fi

}

URL_LIST="www.baidu.com www.agasgf.com"

for URL in $URL_LIST; do

    check_url $URL

    check_url $URL

    check_url $URL

    echo "Warning: $URL Access failure!"

done

方法2:错误次数保存到变量

!/bin/bash  
URL_LIST="www.baidu.com www.agasgf.com"

for URL in $URL_LIST; do

    FAIL_COUNT=0

    for ((i=1;i<=3;i++)); do

        HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)

        if [ $HTTP_CODE -ne 200 ]; then

            let FAIL_COUNT++

        else

            break

        fi

    done

    if [ $FAIL_COUNT -eq 3 ]; then

        echo "Warning: $URL Access failure!"

    fi

done

方法3:错误次数保存到数组

!/bin/bash  
URL_LIST="www.baidu.com www.agasgf.com"

for URL in $URL_LIST; do

    NUM=1

    while [ $NUM -le 3 ]; do

        HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)

        if [ $HTTP_CODE -ne 200 ]; then

            FAIL_COUNT[$NUM]=$IP  #创建数组,以$NUM下标,$IP元素

            let NUM++

        else

            break

        fi

    done

    if [ ${#FAIL_COUNT[]} -eq 3 ]; then

        echo "Warning: $URL Access failure!"

        unset FAIL_COUNT[]    #清空数组

    fi

done

 
10、检查MySQL主从同步状态
!/bin/bash  
USER=bak

PASSWD=123456

IO_SQLSTATUS=$(mysql -u$USER -p$PASSWD -e  show slave statusG  |awk -F:  /Slave._Running/{gsub(": ",":");print $0} )  #gsub去除冒号后面的空格

for i in $IO_SQL_STATUS; do

    THREAD_STATUS_NAME=${i%:}

    THREAD_STATUS=${i#*:}

    if [ "$THREAD_STATUS" != "Yes" ]; then

        echo "Error: MySQL Master-Slave $THREAD_STATUS_NAME status is $THREAD_STATUS!"

    fi

done

One thought on “bash

  • 2021-05-17 at 19:31
    Permalink

    #删除temp文件的重复行
    awk ‘!($0 in array) { array[$0]; print }’ temp

    #查看最长使用的10个unix命令
    awk ‘{print $1}’ ~/.bash_history | sort | uniq -c | sort -rn | head -n 10

    #查看机器的ip列表
    ifconfig -a | awk ‘/Bcast/{print $2}’ | cut -c 5-19

    #查看机器的每个远程链接机器的连接数
    netstat -antu | awk ‘$5 ~ /[0-9]:/{split($5, a, “:”); ips[a[1]]++} END {for (ip in ips) print ips[ip], ip | “sort -k1 -nr”}’

    #查看某个进程打开的socket数量
    ps aux | grep [process] | awk ‘{print $2}’ | xargs -I % ls /proc/%/fd | wc -l

    #查看无线网络的ip
    sudo ifconfig wlan0 | grep inet | awk ‘NR==1 {print $2}’ | cut -c 6-

    #批量重命名文件
    find . -name ‘*.jpg’ | awk ‘BEGIN{ a=0 }{ printf “mv %s name%01d.jpg\n”, $0, a++ }’ | bash

    #查看某个用户打开的文件句柄列表
    for x in `ps -u 500 u | grep java | awk ‘{ print $2 }’`;do ls /proc/$x/fd|wc -l;done

    #计算文件temp的第一列的值的和
    awk ‘{s+=$1}END{print s}’ temp

    #查看最常用的命令和使用次数
    history | awk ‘{if ($2 == “sudo”) a[$3]++; else a[$2]++}END{for(i in a){print a[i] ” ” i}}’ | sort -rn | head

    #查找某个时间戳的文件列表
    cp -p `ls -l | awk ‘/Apr 14/ {print $NF}’` /usr/users/backup_dir

    #格式化输出当前的进程信息
    ps -ef | awk -v OFS=”\n” ‘{ for (i=8;i<=NF;i++) line = (line ? line FS : "") $i; print NR ":", $1, $2, $7, line, ""; line = "" }' #查看输入数据的特定位置的单个字符 echo "abcdefg"|awk 'BEGIN {FS="''"} {print $2}' #打印行号 ls | awk '{print NR "\t" $0}' #打印当前的ssh 客户端 netstat -tn | awk '($4 ~ /:22\s*/) && ($6 ~ /^EST/) {print substr($5, 0, index($5,":"))}' #打印文件第一列不同值的行 awk '!array[$1]++' file.txt #打印第二列唯一值 awk '{ a[$2]++ } END { for (b in a) { print b } }' file #查看系统所有分区 awk '{if ($NF ~ "^[a-zA-Z].*[0-9]$" && $NF !~ "c[0-9]+d[0-9]+$" && $NF !~ "^loop.*") print "/dev/"$NF}' /proc/partitions #查看2到100所有质数 for num in `seq 2 100`;do if [ `factor $num|awk '{print $2}'` == $num ];then echo -n "$num ";fi done;echo #查看第3到第6行 awk 'NR >= 3 && NR <= 6' /path/to/file #逆序查看文件 awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j–] }’

    #打印99乘法表
    seq 9 | sed ‘H;g’ | awk -v RS=” ‘{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *