目录
一、基本文件展示
(一)confd-general-config.conf文件展示
(二)相关数据展示
二、相关修改变更值代码展示
(一)思路总结
getConfigValue函数
writeConfigValue函数
(二)脚本代码实现
(三)潜在的缺点分析
三、优化与扩展
(一)优化思路分析
(二)脚步验证
四、总结
干货分享,感谢您的阅读!Shell脚本在现代软件开发中扮演着重要角色,特别是在配置管理方面。本文将讨论如何通过优化Shell脚本,提升配置管理的效率和质量,使其更具可读性、可维护性和实用性。
一、基本文件展示
首先,我们来看看当前的配置文件内容和部分相关数据:
(一)confd-general-config.conf文件展示
以下是应用程序的配置文件,包含了各项重要的服务和连接信息:
# cat confd-general-config.conf # ETCD服务器的主机IP和端口配置 ETCD_SERVER_HOSTIP=192.168.3.103 ETCD_SERVER_PORT=2379 # 内部网络段设置,用于内部通信和地址分配 innernetworksegement=192.168.3 # PostgreSQL数据库主从连接地址 pgconn=10.47.245.110:13306,10.47.245.110:23306 # Kafka消息队列的连接地址,包括多个Broker节点 kafkaconn=10.47.223.223:9090,10.47.223.223:9091,10.47.223.223:9092 # Zookeeper的连接地址,用于协调Kafka集群 zkconn=10.47.223.223:2181,10.47.223.223:2182,10.47.223.223:2183 # Redis缓存服务器的连接地址,多节点部署 redisconn=10.47.223.223:8000,10.47.223.223:8001,10.47.223.223:8002 # Kubernetes API服务器的URL地址 k8sapiserverurl=10.47.225.97:8080 # Kubernetes使用的NFS主机地址 k8snfshost=10.47.225.92 # 联创服务的URL地址,用于特定服务调用 lianchuang_url=61.160.190.227:8298(二)相关数据展示
# Kafka stream spring.cloud.stream.kafka.binder.zk-nodes=10.47.223.223:2181,10.47.223.223:2182,10.47.223.223:2183 spring.cloud.stream.kafka.binder.brokers=10.47.223.223:9090,10.47.223.223:9091,10.47.223.223:9092 spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_PLAINTEXT spring.cloud.stream.kafka.binder.configuration.sasl.mechanism=PLAIN二、相关修改变更值代码展示
(一)思路总结
主要思路是从配置文件中获取特定键的值,并将这些值应用于应用程序的配置文件中。
getConfigValue函数
- 函数接受两个参数:文件名和键名,从配置文件中提取相应键的值。
- 使用grep和awk命令来解析配置文件,提取键值对,并去除额外的空格。
writeConfigValue函数
- 定义多个变量来存储从配置文件中获取的不同连接和地址信息。
- 如果应用程序的配置文件(如application.properties)存在,则根据获取的值更新配置文件。
- 对于IP段、ZooKeeper、Kafka和联创URL等关键信息,使用sed命令将其写入应用程序配置文件中。
- 如果存在bootstrap.properties文件,则根据需要更新eureka客户端的服务URL。
(二)脚本代码实现
function getConfigValue { [ $# -ne 2 ] && echo "function getConfigValue arguments error" local fileName=$1 local key=$2 echo `cat ${fileName}| grep "${key}"| grep "=" | awk -F= '{print $2}' | tr -d " "` } function writeConfigValue() { K8SCONFIGDIR=/home/zyf/confdconfig K8SCONFIGFILE=${K8SCONFIGDIR}/confd-general-config.conf DBMASTURL=`getConfigValue ${K8SCONFIGFILE} pgconn | awk -F ',' '{print $1}'` DBSLAVEURL=`getConfigValue ${K8SCONFIGFILE} pgconn | awk -F ',' '{print $2}'` REDISURL=`getConfigValue ${K8SCONFIGFILE} redisconn` KAFKAURL=`getConfigValue ${K8SCONFIGFILE} kafkaconn` ZOOKEEPURL=`getConfigValue ${K8SCONFIGFILE} zkconn` IPSEGEMENT=`getConfigValue ${K8SCONFIGFILE} innernetworksegement` LIANCHUANGURL=`getConfigValue ${K8SCONFIGFILE} lianchuang_url` if [ -f ${CONFIGDIR}/application.properties ] then if [ -n ${IPSEGEMENT} ] then sed -i -e "/^genid/s/\/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]./\/${IPSEGEMENT}./g" ${CONFIGDIR}/application.properties fi if [ -n ${ZOOKEEPURL} ] then sed -i -e "/^spring.cloud.stream.kafka.binder.zk-nodes/s/spring.cloud.stream.kafka.binder.zk-nodes=.*/spring.cloud.stream.kafka.binder.zk-nodes=${ZOOKEEPURL}/" ${CONFIGDIR}/application.properties fi if [ -n ${KAFKAURL} ] then sed -i -e "/^kafka.binder.brokers/s/kafka.binder.brokers=.*/kafka.binder.brokers=${KAFKAURL}/" ${CONFIGDIR}/application.properties sed -i -e "/^spring.cloud.stream.kafka.binder.brokers/s/spring.cloud.stream.kafka.binder.brokers=.*/spring.cloud.stream.kafka.binder.brokers=${KAFKAURL}/" ${CONFIGDIR}/application.properties fi if [ -n ${LIANCHUANGURL} ] then BRFOREVALUE=`getConfigValue ${CONFIGDIR}/application.properties lianchuang.url` BRFORE=${BRFOREVALUE#*//} sed -i "s/${BRFORE}/${LIANCHUANGURL}/g" ${CONFIGDIR}/application.properties fi fi if [ -f ${CONFIGDIR}/bootstrap.properties ] then if [ -n ${IPSEGEMENT} ] then sed -i -e "/^eureka.client.serviceUrl.defaultZone/s/\/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]./\/${IPSEGEMENT}./g" ${CONFIGDIR}/bootstrap.properties fi fi }(三)潜在的缺点分析
安全性问题:getConfigValue函数没有对文件路径或键名进行有效性验证,可能会导致安全漏洞,如路径注入或命令注入攻击。
错误处理不足:getConfigValue和writeConfigValue函数中没有充分的错误处理机制,如文件不存在或键名未找到时可能会导致意外终止或未定义行为。
可读性和维护性:使用反引号和多个sed命令可能会使代码难以阅读和维护。建议使用更现代的Shell语法 $(...) 代替反引号。
依赖于外部文件路径:函数中使用的配置文件路径(如CONFIGDIR变量)是外部硬编码的,不利于代码的移植和部署。
缺乏注释和文档:缺乏足够的注释和文档,不利于他人理解和维护代码。
三、优化与扩展
我们可以对这个脚本进行优化,以提高其可读性、灵活性和稳健性。
(一)优化思路分析
- 增加注释:为每个函数和重要代码段添加注释,以提高可读性和可维护性。
- 参数验证:加强参数验证和错误处理,确保脚本的稳健性。
- 使用函数:将重复代码提取到函数中,以提高代码的复用性。
- 配置文件路径:将配置文件路径和其他常量定义在脚本的开头,方便管理和修改。
- 日志记录:添加日志记录功能,便于调试和监控。
- 命令行参数:允许通过命令行参数传递一些常用参数,以增加灵活性。
- 避免使用反引号:使用
$(...)代替反引号...,因为前者更具可读性。
(二)脚步验证
#!/bin/bash # Constants K8SCONFIGDIR=/home/zyf/confdconfig K8SCONFIGFILE=${K8SCONFIGDIR}/confd-general-config.conf CONFIGDIR=/path/to/config # 修改为实际路径 # Function to get configuration value getConfigValue() { if [ $# -ne 2 ]; then echo "function getConfigValue arguments error" return 1 fi local fileName=$1 local key=$2 grep -E "^${key}=" "${fileName}" | awk -F= '{print $2}' | tr -d " " } # Function to write configuration values writeConfigValue() { # Fetch values from the configuration file DBMASTURL=$(getConfigValue "${K8SCONFIGFILE}" pgconn | awk -F ',' '{print $1}') DBSLAVEURL=$(getConfigValue "${K8SCONFIGFILE}" pgconn | awk -F ',' '{print $2}') REDISURL=$(getConfigValue "${K8SCONFIGFILE}" redisconn) KAFKAURL=$(getConfigValue "${K8SCONFIGFILE}" kafkaconn) ZOOKEEPURL=$(getConfigValue "${K8SCONFIGFILE}" zkconn) IPSEGEMENT=$(getConfigValue "${K8SCONFIGFILE}" innernetworksegement) LIANCHUANGURL=$(getConfigValue "${K8SCONFIGFILE}" lianchuang_url) # Update application.properties if [ -f "${CONFIGDIR}/application.properties" ]; then [ -n "${IPSEGEMENT}" ] && sed -i -e "/^genid/s/\/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\./\/${IPSEGEMENT}./g" "${CONFIGDIR}/application.properties" [ -n "${ZOOKEEPURL}" ] && sed -i -e "/^spring.cloud.stream.kafka.binder.zk-nodes/s/.*/spring.cloud.stream.kafka.binder.zk-nodes=${ZOOKEEPURL}/" "${CONFIGDIR}/application.properties" [ -n "${KAFKAURL}" ] && sed -i -e "/^kafka.binder.brokers/s/.*/kafka.binder.brokers=${KAFKAURL}/" "${CONFIGDIR}/application.properties" [ -n "${KAFKAURL}" ] && sed -i -e "/^spring.cloud.stream.kafka.binder.brokers/s/.*/spring.cloud.stream.kafka.binder.brokers=${KAFKAURL}/" "${CONFIGDIR}/application.properties" if [ -n "${LIANCHUANGURL}" ]; then BRFOREVALUE=$(getConfigValue "${CONFIGDIR}/application.properties" lianchuang.url) BRFORE=${BRFOREVALUE#*//} sed -i "s/${BRFORE}/${LIANCHUANGURL}/g" "${CONFIGDIR}/application.properties" fi fi # Update bootstrap.properties if [ -f "${CONFIGDIR}/bootstrap.properties" ]; then [ -n "${IPSEGEMENT}" ] && sed -i -e "/^eureka.client.serviceUrl.defaultZone/s/\/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\./\/${IPSEGEMENT}./g" "${CONFIGDIR}/bootstrap.properties" fi } # Main script execution writeConfigValue四、总结
我们详细展示了现有的配置文件内容和相关代码,并针对原始脚本提出了优化建议。优化后的脚本不仅提高了代码的可读性、灵活性和稳健性,还增加了实用性和可维护性。具体的优化措施包括增加注释、加强参数验证、提取重复代码到函数中、定义常量、添加日志记录功能、支持命令行参数传递以及使用更具可读性的语法结构。希望对以后的编码有所帮助。