实用shell脚本(菜单调用、Expect实现SSH免交、数组、计算时间差)
1、、定时清空文件内容,定时记录文件大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/bin/bash ################################################################ #每小时执行一次脚本(任务计划),当时间为0点或12点时,将目标目录下的所有文件内 #容清空,但不删除文件,其他时间则只统计各个文件的大小,一个文件一行,输出到以时#间和日期命名的文件中,需要考虑目标目录下二级、三级等子目录的文件 ################################################################ logfile=/tmp/`date +%H-%F`. log n=`date +%H` if [ $n -eq 00 ] || [ $n -eq 12 ] then #通过for循环,以find命令作为遍历条件,将目标目录下的所有文件进行遍历并做相应操作 for i in `find /data/ log / -type f` do true > $i done else for i in `find /data/ log / -type f` do du -sh $i >> $logfile done fi |
2、计算文档每行出现的数字个数,并计算整个文档的数字总数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/bin/bash ######################################################### #计算文档每行出现的数字个数,并计算整个文档的数字总数 ######################################################## #使用awk只输出文档行数(截取第一段) n=`wc -l a.txt|awk '{print $1}' ` sum=0 #文档中每一行可能存在空格,因此不能直接用文档内容进行遍历 for i in `seq 1 $n` do #输出的行用变量表示时,需要用双引号 line=`sed -n "$i" p a.txt` #wc -L选项,统计最长行的长度 n_n=`echo $line|sed s '/[^0-9]//' g|wc -L` echo $n_n sum=$[$sum+$n_n] done echo "sum:$sum" |
3、从FTP服务器下载文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/bash if [ $# -ne 1 ]; then echo "Usage: $0 filename" fi dir=$(dirname $1) file=$(basename $1) ftp -n -v << EOF # -n 自动登录 open 192.168.1.10 # ftp服务器 user admin password binary # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误 cd $dir get "$file" EOF |
4、连续输入5个100以内的数字,统计和、最小和最大
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #!/bin/bash # 定义数组,用于存储用户输入的五个数 nums=() # 循环读取用户输入的五个数 for (( i=0; i<5; i++ )) do echo "请输入一个100以内的数:" read num # 判断输入是否符合要求 while [[ $num -lt 0 || $num -gt 100 ]] do echo "输入不合法,请重新输入一个100以内的数:" read num done # 将合法的输入添加到数组中 nums[$i]=$num done # 计算数组中所有数的和 sum=0 for num in ${nums[@]} do let sum+=num done # 输出五个数、它们的最大值和最小值以及它们的和 echo "您输入的五个数为:${nums[@]}" echo "它们的最大值为:$(echo ${nums[@]} | tr ' ' '\n' | sort -n | tail -n 1)" echo "它们的最小值为:$(echo ${nums[@]} | tr ' ' '\n' | sort -n | head -n 1)" echo "它们的和为:$sum" |
改进版:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #!/bin/bash # 定义变量 count=0 max=0 min=100 # 定义数组 declare -a arr # 循环读入数值 while [ $count -lt 5 ] do # 读入数值 read -p "请输入第 $((count+1)) 个数(100以内):" num # 判断输入是否合法 if [[ ! $num =~ ^[0-9]+$ ]] || [ $num -lt 0 ] || [ $num -gt 100 ] then echo "输入不合法,请重新输入。" else # 判断是否为最大值或最小值 if [ $num -gt $max ] then max=$num fi if [ $num -lt $min ] then min=$num fi # 将数值保存到数组中 arr[$count]=$num count=$((count+1)) fi done # 判断是否存在输入不合法的数字 #if [[ " ${arr[@]} " =~ " -1 " ]] || [[ " ${arr[@]} " =~ " 101 " ]] #then # echo "存在输入不合法的数字,请重新运行脚本。" #else # 输出符合要求的5个数,以及最大值和最小值 echo "符合要求的5个数为:${arr[0]} ${arr[1]} ${arr[2]} ${arr[3]} ${arr[4]}" echo "最大值为:$max" echo "最小值为:$min" #fi |
注:
1、[[ ! ]] 的含义
是对用户输入进行正则表达式匹配,判断用户输入是否为数字。
具体来说,^ 表示匹配字符串开头,[0-9] 表示匹配数字,+ 表示匹配前面字符一次或多次,$ 表示匹配字符串结尾。
所以这个正则表达式的意思是:匹配一个不以数字开头或以数字结尾的字符串,即判断是否存在非数字字符。
2、if [[ ! ]] || [ num -gt 100 ]的含义
||则与&&相反。如果||左边的命令1未执行成功,那么就执行||右边的命令2;即“如果这个命令执行失败了||那么就执行这个命令”。
-
命令之间使用 || 连接,实现逻辑或的功能。
-
只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。
-
只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行。
5、监测Nginx访问日志502情况,并做相应动作
假设服务器环境为lnmp,近期访问经常出现502现象,且502错误在重启php-fpm服务后消失,因此需要编写监控脚本,一旦出现502,则自动重启php-fpm服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #场景: #1.访问日志文件的路径:/data/log/access.log #2.脚本死循环,每10秒检测一次,10秒的日志条数为300条,出现502的比例不低于10%(30条)则需要重启php-fpm服务 #3.重启命令为:/etc/init.d/php-fpm restart #!/bin/bash ########################################################### #监测Nginx访问日志502情况,并做相应动作 ########################################################### log =/data/ log /access. log N=30 #设定阈值 while : do #查看访问日志的最新300条,并统计502的次数 err=`tail -n 300 $ log |grep -c '502" ' ` if [ $err -ge $N ] then /etc/init.d/php-fpm restart 2> /dev/null #设定60s延迟防止脚本bug导致无限重启php-fpm服务 sleep 60 fi sleep 10 done |
6、将结果分别赋值给变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 应用场景:希望将执行结果或者位置参数赋值给变量,以便后续使用。 方法1: for i in $(echo "4 5 6" ); do eval a$i=$i done echo $a4 $a5 $a6 方法2:将位置参数192.168.1.1{1,2}拆分为到每个变量 num=0 for i in $(eval echo $*); do #eval将{1,2}分解为1 2 let num+=1 eval node${num}= "$i" done echo $node1 $node2 $node3 # bash a.sh 192.168.1.1{1,2} 192.168.1.11 192.168.1.12 方法3: arr=(4 5 6) INDEX1=$(echo ${arr[0]}) INDEX2=$(echo ${arr[1]}) INDEX3=$(echo ${arr[2]}) |
7、输入数字运行相应命令(菜单)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #!/bin/bash ############################################################## #输入数字运行相应命令 ############################################################## echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit " while : do #捕获用户键入值 read -p "please input number :" n n1=`echo $n|sed s '/[0-9]//' g` #空输入检测 if [ -z "$n" ] then continue fi #非数字输入检测 if [ -n "$n1" ] then exit 0 fi break done case $n in 1) date ;; 2) ls ;; 3) who ;; 4) pwd ;; 0) break ;; #输入数字非1-4的提示 *) echo "please input number is [1-4]" esac |
8、Expect实现SSH免交互执行命令
Expect是一个自动交互式应用程序的工具,如telnet,ftp,passwd等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 需先安装expect软件包。 方法1:EOF标准输出作为expect标准输入 #!/bin/bash USER=root PASS=123.com IP=192.168.1.120 expect << EOF set timeout 30 spawn ssh $USER@$IP expect { "(yes/no)" {send "yes\r" ; exp_continue} "password:" {send "$PASS\r" } } expect "$USER@*" {send "$1\r" } expect "$USER@*" {send "exit\r" } expect eof EOF 方法2: #!/bin/bash USER=root PASS=123.com IP=192.168.1.120 expect -c " spawn ssh $USER@$IP expect { \"(yes/no)\" {send \"yes\r\"; exp_continue} \"password:\" {send \"$PASS\r\"; exp_continue} \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue} }" 方法3:将expect脚本独立出来 登录脚本: # cat login.exp #!/usr/bin/expect set ip [lindex $argv 0] set user [lindex $argv 1] set passwd [lindex $argv 2] set cmd [lindex $argv 3] if { $argc != 4 } { puts "Usage: expect login.exp ip user passwd" exit 1 } set timeout 30 spawn ssh $user@$ip expect { "(yes/no)" {send "yes\r" ; exp_continue} "password:" {send "$passwd\r" } } expect "$user@*" {send "$cmd\r" } expect "$user@*" {send "exit\r" } expect eof 执行命令脚本:写个循环可以批量操作多台服务器 #!/bin/bash HOST_INFO=user_info.txt for ip in $(awk '{print $1}' $HOST_INFO) do user=$(awk -v I= "$ip" 'I==$1{print $2}' $HOST_INFO) pass=$(awk -v I= "$ip" 'I==$1{print $3}' $HOST_INFO) expect login.exp $ip $user $pass $1 done Linux主机SSH连接信息: # cat user_info.txt 192.168.1.120 root 123456 |
9、创建10个用户,并分别设置密码,密码要求10位且包含大小写字母以及数字,最后需要把每个用户的密码存在指定文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/bin/bash ############################################################## #创建10个用户,并分别设置密码,密码要求10位且包含大小写字母以及数字 #最后需要把每个用户的密码存在指定文件中 #前提条件:安装mkpasswd命令 ############################################################## #生成10个用户的序列(00-09) for u in `seq -w 0 09` do #创建用户 useradd user_$u #生成密码 p=`mkpasswd -s 0 -l 10` #从标准输入中读取密码进行修改(不安全) echo $p|passwd --stdin user_$u #常规修改密码 echo -e "$p\n$p" |passwd user_$u #将创建的用户及对应的密码记录到日志文件中 echo "user_$u $p" >> /tmp/userpassword done |
10、批量修改服务器用户密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | Linux主机SSH连接信息:旧密码 # cat old_pass.txt 192.168.18.217 root 123456 22 192.168.18.218 root 123456 22 内容格式:IP User Password Port SSH远程修改密码脚本:新密码随机生成 https: //www.linuxprobe.com/books #!/bin/bash OLD_INFO=old_pass.txt NEW_INFO=new_pass.txt for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO) PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO) PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO) NEW_PASS=$(mkpasswd -l 8) # 随机密码 echo "$IP $USER $NEW_PASS $PORT" >> $NEW_INFO expect -c " spawn ssh -p$PORT $USER@$IP set timeout 2 expect { \"(yes/no)\" {send \"yes\r\";exp_continue} \"password:\" {send \"$PASS\r\";exp_continue} \"$USER@*\" {send \"echo \'$NEW_PASS\' |passwd --stdin $USER\r exit \r\";exp_continue} }" done 生成新密码文件: # cat new_pass.txt 192.168.18.217 root n8wX3mU% 22 192.168.18.218 root c87;ZnnL 22 |
11、判断用户输入的是否为IP地址
方法1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/bin/bash function check_ip(){ IP=$1 VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}' ) if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/ null ; then if [ $VALID_CHECK == "yes" ]; then echo "$IP available." else echo "$IP not available!" fi else echo "Format error!" fi } check_ip 192.168.1.1 check_ip 256.1.1.1 |
方法2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/bin/bash function check_ip(){ IP=$1 if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FIELD1=$(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 ]; then echo "$IP available." else echo "$IP not available!" fi else echo "Format error!" fi } check_ip 192.168.1.1 check_ip 256.1.1.1 |
增强版:加个死循环,如果IP可用就退出,不可用提示继续输入,并使用awk判断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/bin/bash function check_ip(){ local IP=$1 VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}' ) if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/ null ; then if [ $VALID_CHECK == "yes" ]; then return 0 else echo "$IP not available!" return 1 fi else echo "Format error! Please input again." return 1 fi } while true ; do read -p "Please enter IP: " IP check_ip $IP [ $? -eq 0 ] && break || continue done |
12、jar包启动脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #!/bin/bash ENV=dev RUNNING_USER=root ADATE=`date +%Y%m%d%H%M%S` APP_NAME=jar包名 APP_HOME=`pwd` dirname $0|grep "^/" >/dev/ null if [ $? -eq 0 ];then APP_HOME=`dirname $0` else dirname $0|grep "^\." >/dev/ null retval=$? if [ $retval -eq 0 ];then APP_HOME=`dirname $0|sed "s#^.#$APP_HOME#" ` else APP_HOME=`dirname $0|sed "s#^#$APP_HOME/#" ` fi fi if [ ! -d "$APP_HOME/logs" ];then mkdir $APP_HOME/logs fi LOG_PATH=$APP_HOME/logs/$APP_NAME. out GC_LOG_PATH=$APP_HOME/logs/gc-$APP_NAME-$ADATE.log #JMX监控需用到 JMX= "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1091 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" #JVM参数 JVM_OPTS= "-Dname=$APP_NAME -Djeesuite.configcenter.profile=$ENV -Duser.timezone=Asia/Shanghai -Xms2046M -Xmx2046M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -Xloggc:$GC_LOG_PATH -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" JAR_FILE=$APP_NAME.jar pid=0 start(){ checkpid if [ ! -n "$pid" ]; then # JAVA_CMD="nohup java -jar $JVM_OPTS $JAR_FILE > $LOG_PATH 2>&1 &" # su - $RUNNING_USER -c "$JAVA_CMD" nohup java -jar $JVM_OPTS $JAR_FILE > $LOG_PATH 2>&1 --xjar.keyfile= params .x & echo "---------------------------------" echo "启动完成,按CTRL+C退出日志界面即可>>>>>" echo "---------------------------------" sleep 2s tail -f $LOG_PATH else echo "$APP_NAME is runing PID: $pid" fi } status(){ checkpid if [ ! -n "$pid" ]; then echo "$APP_NAME not runing" else echo "$APP_NAME runing PID: $pid" fi } checkpid(){ pid=`ps -ef |grep $JAR_FILE |grep -v grep |awk '{print $2}' ` } stop(){ checkpid if [ ! -n "$pid" ]; then echo "$APP_NAME not runing" else echo "$APP_NAME stop..." kill -9 $pid fi } restart(){ stop sleep 1s start } case $1 in start) start;; stop) stop;; restart) restart;; status) status;; *) echo "require start|stop|restart|status" ;; esac |
13、菜单选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | #!/usr/bin/bash ######################## #微服务日志路径调用变量 ### LogAudience=/service/audience-service/log ### LogsAudience=/service/audience-service/logs ### LogUser=/service/user-service/log ### LogsUser=/service/user-service/logs ### LogsGateway=/service/gateway/logs ### LogsImService=/service/im-service/logs ### LogsLogistics=/service/logistics-service/logs ### LogMall=/service/mall-service/log ### LogsMall=/service/mall-service/logs ### LogOrder=/service/order-service/log ### LogsOrder=/service/order-service/logs ### LogsPay=/service/pay-service/logs ### LogsTestingd=/service/testingd-service/logs ### #服务脚本启动路径################################################################### StartPath1=/service/audience-service ### StartPath2=/service/user-service ### StartPath3=/service/gateway ### StartPath4=/service/im-service ### StartPath5=/service/logistics-service ### StartPath6=/service/mall-service ### StartPath7=/service/order-service ### StartPath8=/service/pay-service ### StartPath9=/service/testingd-service ### #################################################################################### #################################################################################### #set -x #### #clear #### # 定义多个函数可以调用多次 #### #################################################################################### Tailflogs1(){ echo -e "\033[34m******************1. 正常日志查看****************** \033[0m" cat <<-EOF 1. audience-service-info.log 2. audience-service. out 3. user-service-info.log 4. user-service. out 5. wmsx-gateway. out 6. im-service. out 7. logistics-service. out 8. mallinfo 9. mall-service. out 10. order-service-info.log 11. order-service. out 12. pay-service. out 13. testingd-service. out EOF echo -e "\033[34m*************************************************** \033[0m" } Tailflogs1 TailfEeeor2(){ echo -e "\033[33m*****************2. 错误日志查看******************* \033[0m" cat <<-EOF 15. audience-service-error.log 16. mall-service-mallerror.log 17. order-service-error.log 18. user-service-error.log EOF echo -e "\033[33m*************************************************** \033[0m" } TailfEeeor2 StartJar(){ echo -e "\033[32m******************3. 服务启动********************** \033[0m" cat <<-EOF 20. audience-service 21. user-service 22. wmsx-gateway 23. im-service 24. logistics-service 25. mall-service 26. order-service 27. pay-service 28. testingd-service 29. help EOF echo -e "\033[32m*************************************************** \033[0m" } StartJar echo -e "\003" read -p "欢迎加入微媒云播请选择: " software case $software in 1) clear Tailflogs1 read -p "日志查看: " Tailflogs1 case $Tailflogs1 in 1) tailf $LogAudience/info.log ;; 2) tailf $LogsAudience/audience-service. out ;; 3) tailf $LogUser/info.log ;; 4) tailf $LogsUser/user-service. out ;; 5) tailf $LogsGateway/wmsx-gateway. out ;; 6) tailf $LogsImService/im-service. out ;; 7) tailf $LogsLogistics/logistics-service. out ;; 8) tailf $LogMall/mallinfo.log ;; 9) tailf $LogsMall/mall-service. out ;; 10) tailf $LogOrder/info.log ;; 11) tailf $LogsOrder/order-service. out ;; 12) tailf $LogsPay/pay-service. out ;; 13) tailf $LogsTestingd/testingd-service. out ;; 14) clear ;; esac ;; 2) TailfEeeor2 read -p "错误日志: " TailfEeeor2 case $TailfEeeor2 in 15) tailf $LogAudience/error.log ;; 16) tailf $LogMall/mallerror.log ;; 17) tailf $LogOrder/error.log ;; 18) tailf $LogUser/error.log ;; 19) clear ;; esac ;; 3) StartJar read -p "服务启动: " StartJar case $StartJar in 20) /bin/bash $StartPath1/audience-service.sh start ;; 21) /bin/bash $StartPath2/user-service.sh start ;; 22) /bin/bash $StartPath3/gateway-service.sh start ;; 23) /bin/bash $StartPath4/im-service.sh start ;; 24) /bin/bash $StartPath5/logistics-service.sh start ;; 25) /bin/bash $StartPath6/mall-service.sh start ;; 26) /bin/bash $StartPath7/order-service.sh start ;; 27) /bin/bash $StartPath8/pay-service.sh start ;; 28) /bin/bash $StartPath9/testingd-service.sh start ;; 29) exit esac esac |
14、判断用户输入,选用不同的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #!/bin/bash ###函数1 ipp (){ ###接收变量 exec < $1 while read a do sring=`curl -s "http://ip138.com/ips138.asp?ip=${a}&action=2" | iconv -f gb2312 -t utf-8|grep '<ul class="ul1"><li>' |awk -F '<' '{print $4}' | awk -F ':' '{print $2}' ` echo $a $sring done } ###函数2 cha() { srin=`curl -s "http://ip138.com/ips138.asp?ip=${1}&action=2" | iconv -f gb2312 -t utf-8|grep '<ul class="ul1"><li>' |awk -F '<' '{print $4}' | awk -F ':' '{print $2}' ` echo $1 $srin } ###函数3 firewal() { for i in `lastb|awk '{print $3}' | sort | uniq |egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ` do sri=`curl -s "http://ip138.com/ips138.asp?ip=${i}&action=2" | iconv -f gb2312 -t utf-8|grep '<ul class="ul1"><li>' |awk -F '<' '{print $4}' | awk -F ':' '{print $2}' ` echo $i $sri done } ###判断用户输入 if [ "$1" == "-f" ];then ipp $2 elif [ "$1" == "-i" ];then cha $2 elif [ "$1" == "-q" ];then firewal ###输出正确用法参数 else echo "-f + 文件 批量显示ip所在地" echo "-i + ip地址 显示ip所在地" echo "-q 显示尝试登陆此服务器的ip所在地" fi |
15、重启系统服务
#!/bin/bash # Function to reboot worker nodes function reboot_worker() { nodes=$( cat /backup/node-list | grep - v "$(hostname)" | grep - v "${master_name}" | awk -F ',' '{print $1}' ) echo -e "master node is: ${master_name}\n" for node in ${nodes}; do echo -e "Rebooting worker node: ${node}\n" ssh $node '(systemctl stop docker.socket && systemctl stop docker.service && sleep 10 && reboot)' done } # Function to reboot local host function reboot_localhost() { systemctl stop docker.socket systemctl stop docker.service sleep 10 reboot } # Check if the current node is the Swarm management node (Leader) lines=$(docker node ls 2> /dev/null | grep Leader | awk -F ' ' '{print $3}' | wc -l) if [ ${lines} - eq 1 ]; then echo "Currently on the master node!! Recommended to execute on worker node!!" read -p "Are you sure to execute on the master node? (yes/no): " res if [ "${res}" == "yes" ]; then echo "Executing on the master node!" echo "Restarting master $(hostname)" systemctl stop docker.socket systemctl stop docker.service ( sleep 30 && reboot) & nodes=$( cat /backup/node-list | grep - v "$(hostname)" | awk -F ',' '{print $1}' ) if [ -z "$nodes" ]; then echo "The project consists of only one node. Restarting the master node will suffice." else echo "Restarting worker nodes" for node in ${nodes}; do echo "Rebooting worker node: $node" ssh $node '(systemctl stop docker.socket && systemctl stop docker.service && sleep 5 && reboot)' done fi else exit 1 fi else echo "Currently on worker node, as expected." # Check if the node can SSH to other nodes without password nodes=$( cat /backup/node-list | grep - v "$(hostname)" | awk -F ',' '{print $1}' ) for remote_host in ${nodes}; do # Check if local SSH private key file exists (usually ~/.ssh/id_rsa) if [ ! -f ~/. ssh /id_rsa ]; then echo "SSH private key not found, generating one." ssh -keygen -t rsa -b 2048 -f ~/. ssh /id_rsa -N "" fi # Try SSH connection to remote node, setting BatchMode and ConnectTimeout ssh -o BatchMode= yes -o ConnectTimeout=5 $remote_host "echo Connection test; exit 0" 2> /dev/null # Check SSH connection exit code if [ $? - eq 0 ]; then echo "You can SSH to $remote_host without a password." else echo "Error: Unable to SSH to $remote_host without a password. Password required for key synchronization." # Input host password, copy public key to remote host read -p "Enter password for $remote_host: " password # Transfer public key to remote host sshpass -p "$password" ssh -copy- id -i ~/. ssh /id_rsa .pub $remote_host # Try SSH connection again to check if successful ssh -o BatchMode= yes -o ConnectTimeout=5 $remote_host "echo Connection successful; exit 0" 2> /dev/null if [ $? - eq 0 ]; then echo "SSH key successfully copied to $remote_host." else echo "Error: Unable to copy SSH key to $remote_host. Please check password or network connectivity." exit 1 fi fi done # Find out master node hostname and reboot nodes=$( cat /backup/node-list | grep - v "$(hostname)" | awk -F ',' '{print $1}' ) for remote_host in ${nodes}; do ssh $remote_host '(docker node ls 2>/dev/null | grep Leader)' if [ $? - eq 0 ]; then master_name=$( ssh $remote_host "docker node ls 2>/dev/null | grep Leader | awk -F' ' '{print \$3}'" ) echo -e "Start rebooting master node: $master_name \n" ssh $master_name '(systemctl stop docker.socket && systemctl stop docker.service && sleep 10 && reboot)' break fi done echo -e "Start rebooting worker nodes:\n" reboot_worker echo "Start rebooting local host" reboot_localhost fi |
16、计算代码运行的时间差
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!/bin/bash # 记录开始时间及时间戳 start_time=$( date + '%Y-%m-%d %H:%M:%S' ) start_timestamp=$( date +%s) echo "${start_time} Start backup minio." # 在这里执行你的备份操作... sleep 30 # 记录结束时间及时间戳 end_time=$( date + '%Y-%m-%d %H:%M:%S' ) end_timestamp=$( date +%s) echo "${end_time}: Finished backup minio." # 计算并显示总耗时 elapsed_seconds=$((end_timestamp - start_timestamp)) hours=$((elapsed_seconds / 3600)) minutes=$(( (elapsed_seconds / 60) % 60)) seconds=$((elapsed_seconds % 60)) echo "Total time taken: $hours hours $minutes minutes $seconds seconds." |