基于bash的动态参数服务器客户端脚本

请添加图片描述

前言

  • 上一篇文章我们提到了使用yaml-cpp编写了实时检测参数文件config.yaml的文件系统时间自动进行无编译实时动态同步运行程序的参数,本文将使用bash脚本为用户提供一个修改参数的脚本接口,效果如下。
  • 请添加图片描述
  • 基于yaml-cpp的C++参数服务器设计

请添加图片描述

代码分析

  • 老规矩先上全部代码,然后我们结合本代码对bash语法进行分析
#!/bin/bash

# 参数文件路径
CONFIG_FILE="/home/lzh/params_server/src/params_server/src/config.yaml"


# 打印
print_config_key_by_index() {
    local index=$1
    local key="${config_keys[$index]}"
    if [[ -n $key ]]; then
        echo "参数名称: $key"
    else
        echo "无效的序号。"
    fi
}
# 函数用于打印所有配置项并附带序号
print_config() {
    local i=0
    echo "==========================================================="
    while IFS=':' read -r key value
    do
        # 去除value前后的空格
        value=$(echo$value | xargs)
        # 打印配置项及其序号
        echo "$i:$key=$value"
        # 将配置项及其值存入数组
        config_keys[$i]=$key
        config_values[$i]=$value
        ((i++))
    done < <(grep -v '^#' "$CONFIG_FILE" | grep .) # 忽略注释行
    echo "==========================================================="
}

# 函数用于修改配置文件中的参数
modify_config() {
    local index=$1
    local new_value=$2
    local key="${config_keys[$index]}"
    
    if [[ -n $key ]]; then
        # 使用sed替换参数值
        sed -i "/^$key: /c\\$key: $new_value" "$CONFIG_FILE"
        echo "参数 '$key' 已更新为 '$new_value'。"
    else
        echo "无效的序号。"
        return 1
    fi
}
![请添加图片描述](https://i-blog.csdnimg.cn/direct/84c06b95b044470282dd8d582efde4d9.png)

# 读取配置文件并打印
print_config

# 用户交互
while true; do
    echo "请输入要更改的参数序号(或输入 'q' 退出):"
    if ! read -t 180 -r user_input; then
        echo "超时,你到底改不改啊喂!!!。"
        break
    fi

    if [[ $user_input == 'q' ]]; then
        break
    elif ! [[ $user_input =~ ^[0-9]+$ ]]; then
        echo "无效输入。请输入一个数字或 'q' 退出。"
        continue
    elif [ $user_input -ge ${#config_keys[@]} ]; then
        echo "无效序号。请输入一个有效的数字。"
        continue
    fi
    print_config_key_by_index $user_input
    echo "请输入新的值:"
    if ! read -t 180 -r new_value; then
        echo "超时,你到底改不改啊喂!!!"
        break
    fi
    modify_config $user_input "$new_value"
    
    print_config
done


# 打印
print_config_key_by_index() {
    local index=$1
    local key="${config_keys[$index]}"
    if [[ -n $key ]]; then
        echo "参数名称: $key"
    else
        echo "无效的序号。"
    fi
}
  • 上述是一个辅助的打印函数,依次声明了indexkey两个函数内的局部变量,$1代表函数调用时传入的第一个参数,而${config_keys[$index]}是使用索引$index来访问config_keys数组中的元素。
  • bash脚本中,$符号通常用于引用变量。
    • 最常见的用法就是获取变量的值
      myvar="Hello World!"
      echo $myvar  # 输出Hello World!
      
    • 同时如果跟上数字$0,那么这些是位置参数(positional parameters),用于引用传递给脚本的参数。
      echo "本脚本名称: $0"
      echo "本脚本传入第一个参数: $1"
      
    • 其他用法:
      • $$:当前bash进程的PID
      • $?:最后一条命令的退出状态
      • $!:最后一个后台命令的进程ID。
      • $#:传递给脚本的参数数量
  • -n参数用于判断字符串是否非空,上述配合打印函数判断传入索引对应的参数是否存在

# 函数用于打印所有配置项并附带序号
print_config() {
    local i=0
    echo "==========================================================="
    while IFS=':' read -r key value
    do
        # 去除value前后的空格
        value=$(echo$value | xargs)
        # 打印配置项及其序号
        echo "$i:$key=$value"
        # 将配置项及其值存入数组
        config_keys[$i]=$key
        config_values[$i]=$value
        ((i++))
    done < <(grep -v '^#' "$CONFIG_FILE" | grep .) # 忽略注释行
    echo "==========================================================="
}
  • 上述代码读取config.yaml并向用户展示所有的参数并自动对参数进行排序
  • bash中,while循环一般长这样:
    while CONDITION
    do
        # 你的循环
    done
    
  • IFS=':'用于设置分隔符(Internal Field Separator, IFS)为冒号:,这样read命令会将每行按冒号分割成两部分。
  • read -r key value读取每行中的两部分,分别赋值给变量keyvalue。也就是参数名字和参数值
  • value=$(echo$value | xargs)这一行代码很有意思
    • echo$value这里在输出变量value的值
    • |:这是管道操作符,它将echo$value命令的输出作为下一个命令xargs的输入。
    • xargs:这里被用来去除输入的前后空格。当xargs没有接收到其他命令参数时,它会简单地读取其标准输入,去除任何前导和尾随的空白字符,并输出结果。
  • ((i++)):是一个算术扩展(Arithmetic Expansion)的语法,确保bash能顺利执行自增
  • < <(grep -v '^#' "$CONFIG_FILE" | grep .)
    • < <( ... ):这是进程替换(Process Substitution)的语法。这里放在while循环后面是将这行指令的输出作为while循环的输入重定向部分。(类似于输入重定向)
    • grep -v '^#' "$CONFIG_FILE"grep过滤匹配以井号(#)开头的注释
    • grep .进一步过滤掉那些完全由空白字符组成的行。
  • 这样通过grep对参数文件进行注释和空行的过滤后通过进程替换,把整个有效参数文件的输出作为while循环的读取并存储参数名字和参数值,就可以有效向用户呈现参数表后后续的修改逻辑了

# 函数用于修改配置文件中的参数
modify_config() {
    local index=$1
    local new_value=$2
    local key="${config_keys[$index]}"
    
    if [[ -n $key ]]; then
        # 使用sed替换参数值
        sed -i "/^$key: /c\\$key: $new_value" "$CONFIG_FILE"
        echo "参数 '$key' 已更新为 '$new_value'。"
    else
        echo "无效的序号。"
        return 1
    fi
}
  • sed -i "/^$key: /c\\$key: $new_value" "$CONFIG_FILE"这里说说sed
    • -i选项表示直接在文件上进行修改,而不是输出到标准输出。
    • /^$key: /这是一个正则表达式,用于匹配配置文件中的特定行。
    • c:这是sed命令的替换操作符,用于在找到匹配的行时进行替换。
    • \\$key:$new_value替换为新的参数,前面有一个反斜杠\,以防止sed将其作为特殊字符处理。

# 用户交互
while true; do
    echo "请输入要更改的参数序号(或输入 'q' 退出):"
    if ! read -t 180 -r user_input; then
        echo "超时,你到底改不改啊喂!!!。"
        break
    fi

    if [[ $user_input == 'q' ]]; then
        break
    elif ! [[ $user_input =~ ^[0-9]+$ ]]; then
        echo "无效输入。请输入一个数字或 'q' 退出。"
        continue
    elif [ $user_input -ge ${#config_keys[@]} ]; then
        echo "无效序号。请输入一个有效的数字。"
        continue
    fi
    print_config_key_by_index $user_input
    echo "请输入新的值:"
    if ! read -t 180 -r new_value; then
        echo "超时,你到底改不改啊喂!!!"
        break
    fi
    modify_config $user_input "$new_value"
    
    print_config
done
  • 最后的主函数,写了一个死循环
  • read -t 180 它检查用户输入是否在180秒内完成。指定超时参数
  • elif ! [[ $user_input =~ ^[0-9]+$ ]]检测用户是否输入是数字
  • [ $user_input -ge ${#config_keys[@]} ]
    • -ge:这是大于等于(greater than or equal to)的比较运算符。
    • 使用${#array[@]}这种形式可以获取数组的长度
    • 上述用于判断用户输入的序号是否超出参数列表的长度—>是否为无效参数

总结

  • 上述只是使用bash简单实现的一个用户使用参数服务器的bash脚本接口,如有错误,欢迎指正~
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值