实用shell脚本(菜单调用、Expect实现SSH免交、数组、计算时间差)
1、、定时清空文件内容,定时记录文件大小
#!/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、计算文档每行出现的数字个数,并计算整个文档的数字总数
#!/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服务器下载文件
#!/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以内的数字,统计和、最小和最大
#!/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"
改进版:
#!/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、[[ ! $num =~ ^[0-9]+$ ]] 的含义
是对用户输入进行正则表达式匹配,判断用户输入是否为数字。
具体来说,^ 表示匹配字符串开头,[0-9] 表示匹配数字,+ 表示匹配前面字符一次或多次,$ 表示匹配字符串结尾。
所以这个正则表达式的意思是:匹配一个不以数字开头或以数字结尾的字符串,即判断是否存在非数字字符。
2、if [[ ! $num =~ ^[0-9]+$ ]] || [ $num -lt 0 ] || [ $num -gt 100 ]的含义
||则与&&相反。如果||左边的命令1未执行成功,那么就执行||右边的命令2;即“如果这个命令执行失败了||那么就执行这个命令”。
-
命令之间使用 || 连接,实现逻辑或的功能。
-
只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。
-
只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行。
5、监测Nginx访问日志502情况,并做相应动作
假设服务器环境为lnmp,近期访问经常出现502现象,且502错误在重启php-fpm服务后消失,因此需要编写监控脚本,一旦出现502,则自动重启php-fpm服务。
#场景: #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: 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、输入数字运行相应命令(菜单)
#!/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等。
需先安装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位且包含大小写字母以及数字,最后需要把每个用户的密码存在指定文件中
#!/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、批量修改服务器用户密码
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:
#!/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:
#!/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判断。
#!/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包启动脚本
#!/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、菜单选择
#!/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、判断用户输入,选用不同的函数
#!/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、计算代码运行的时间差
#!/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."