• 一次写shell脚本的经历记录——特殊字符惹的祸


    本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流!

    redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要重启。所以把redis集群的状态检查放到了健康检查中,依赖statefulset的原生能力(pod实例ready后才重启下一个,ready后endpoints controller将pod信息更新到endpoints资源对象中),而没有在redis operator中写逻辑去判断。

    需要用redis-cli -h {redis实例IP} ping查看redis是否正常,同时用redis-cli -c -h {redis实例IP} -a {redis密码} cluster info输出的信息解析cluster_state的值是否为ok,以及cluster_known_nodes的值是否为1,判断redis集群是否正常;

    如果redis集群刚创建,cluster_known_nodes为1,cluster_state为fail;

    如果redis集群为纵向扩容(扩CPU、内存)升级重启,cluster_known_nodes不为1,cluster_state为ok时才认为集群正常,才能重启下一个pod。

    因为涉及到字符串相等判断,所以用以下这样判断:

    if [ "$cluster_known_nodes"x = "1"x  ]; then
    .....
    fi
    

    但是判断一直有问题,如下图,在$a后面加个x,会变为在开头覆盖式的加a,结果就是判断结果不相等。
    在这里插入图片描述
    把redis-cli -c -h {redis实例IP} -a {redis密码} cluster info执行的结果重定向到文件里。

    vi 1.txt查看文件,在vi里用set ff命令查看文件格式为unix,但是文件每一行后面都有一个^M的特殊字符,这就是问题所在了。
    在这里插入图片描述

    最主要是通过cat都看不出来特殊字符的存在。
    在这里插入图片描述

    手动把^M特殊字符删掉就好了。
    在这里插入图片描述

    网上说^M是windows格式文本文件的换行符 ,可以用dos2unix命令转为unix格式。但是执行cluster info命令全程在linux中操作,而且重定向到文件中set ff命令看到也是unix格式。这点还是很费解。

    先用sed命令将^M换掉,试了sed 's/^M//g'没有用,所以选择用sed 's? ??g'替换,最终脚本如下。

    if语句的[[]]需要用bash执行,用sh执行会报错[[: not found

    #!/bin/bash
    
    #需要用redis-cli -h {redis实例IP} ping查看redis是否正常
    #用redis-cli -c -h {redis实例IP} -a {redis密码} cluster info输出
    #的信息解析cluster_state的值是否为ok,以及cluster_known_nodes的值是
    #否为1,判断redis集群是否正常;如果redis集群刚创建,cluster_known_nodes
    #为1,cluster_state为fail;如果redis集群为纵向扩容(扩CPU、内存)升级重启
    #cluster_known_nodes不为1,cluster_state为ok时才认为集群正常,才能重启
    #下一个pod,改健康检查脚本旨在维护升级时redis集群状态,不在operator中维护
    # 利用好statefulset一个实例ready后重启下一个pod的特性
    
    pingres=$(redis-cli -h $(hostname) ping)
    
    # cluster_state:ok
    # cluster_slots_assigned:16384
    # cluster_slots_ok:16384      
    # cluster_slots_pfail:0        
    # cluster_slots_fail:0        
    # cluster_known_nodes:6        
    # cluster_size:3                
    # cluster_current_epoch:15      
    # cluster_my_epoch:12          
    # cluster_stats_messages_sent:270782059
    # cluster_stats_messages_received:270732696
    pingres=$(echo "${pingres}" | sed 's?
    ??g')
    if [[ "$pingres"x = "PONG"x ]]; then
        clusterinfo=$(redis-cli -c -h ${PODIP} cluster info)
        # redis-cli -c -h ${PODIP} cluster info output info include ^M(win 
    
    ) char lead to error, so use sed 's?
    ??g'
        clusterknownnodes=$(echo "${clusterinfo}" | grep cluster_known_nodes | sed 's?
    ??g' | awk -F ':' '{print $2}')
        clusterstate=$(echo "${clusterinfo}" | grep cluster_state | sed 's?
    ??g' | awk -F ':' '{print $2}')
    
        echo "clusterknownnodes: ${clusterknownnodes} --- clusterstate: ${clusterstate}"
        # [[ need run this script use /bin/bash instead of /bin/sh
        # if语句的[[]]需要用bash执行,用sh执行会报错[[: not found
        if [[ "${clusterknownnodes}"x = "1"x && "${clusterstate}"x = "ok"x ]]; then
            echo "--1--"
            exit 0
        elif [[ "${clusterknownnodes}"x != "1"x && "${clusterstate}"x = "ok"x ]]; then
            echo "--2--"
            exit 0
        # create redis cluster
        elif [[ "${clusterknownnodes}"x = "1"x && "${clusterstate}"x != "ok"x ]]; then
            echo "--3--"
            exit 0
        elif [[ "${clusterknownnodes}"x != "1"x && "${clusterstate}"x != "ok"x ]]; then
            echo "--4--"
            exit 1
        else
            echo "--5--"
            exit 1
        fi
    else
        exit 1
    fi
    

    一般这种怪异的问题都是脚本里有特殊字符造成的,可以在脚本中set list显示特殊字符。当然windows上编辑过的脚本在linux上运行一般dos2unix test.sh这样转换一下最好,免的遇到麻烦。

    参考:

    shell中括号的特殊用法 linux if多条件判断
    https://www.cnblogs.com/jjzd/p/6397495.html

    运行shell脚本时报错"[[ : not found"解决方法
    https://www.cnblogs.com/han-1034683568/p/7211392.html




    本公众号免费提供csdn下载服务,海量IT学习资源,如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时我们组建了一个技术交流群,里面有很多大佬,会不定时分享技术文章,如果你想来一起学习提高,可以公众号后台回复【2】,免费邀请加技术交流群互相学习提高,会不定期分享编程IT相关资源。


    扫码关注,精彩内容第一时间推给你

    image

  • 相关阅读:
    设计模式----工厂模式
    设计模式----简单工厂
    log4net使用详解
    link/Extended dependency 无法显示连接
    Abp框架之执行Update-Database 命令系列错误
    Index API
    使用Java客户端操作elasticsearch(二)
    elasticsearch之分词插件使用
    使用Java Low Level REST Client操作elasticsearch
    js如何获取隐藏的元素的高度
  • 原文地址:https://www.cnblogs.com/liabio/p/11729945.html
Copyright © 2020-2023  润新知