linux shell

关注公众号 jb51net

关闭
首页 > 脚本专栏 > linux shell > Shell脚本环境变量与配置文件

Shell脚本实现环境变量与配置文件应用指南

作者:鸽芷咕

在Shell脚本编程的世界里,环境变量与配置文件是实现脚本灵活性、可移植性的核心组件,下面就跟随小编一起全面拆解环境变量与配置文件的应用逻辑吧

前言

在Shell脚本编程的世界里,环境变量与配置文件是实现脚本灵活性、可移植性的核心组件。无论是开发自动化部署脚本,还是编写多环境适配的工具,掌握这两项技能都能让你的脚本从“单一场景工具”升级为“通用解决方案”。今天,我们就从基础概念到实战案例,全面拆解环境变量与配置文件的应用逻辑。

一、环境变量:Shell脚本的“全局通行证”

环境变量是Shell中用于存储系统状态、用户偏好、路径信息的“全局变量”,它可以在父进程与子进程之间传递,是脚本与操作系统、不同程序间交互的重要桥梁。

1. 环境变量的核心作用

2. 环境变量的查看与分类

在终端中,通过以下命令可查看环境变量:

环境变量主要分为两类:

3. 环境变量的设置与生效

根据变量的生效范围,设置方式分为三种场景:

(1)临时生效(当前Shell会话)

直接在终端或脚本中执行赋值命令,关闭Shell后变量消失:

# 格式:变量名=值(等号前后无空格)
export APP_ENV=production  # export关键字将变量标记为环境变量(可被子进程继承)
echo $APP_ENV  # 输出:production

(2)用户级永久生效(仅当前用户)

将变量配置写入用户级配置文件(如~/.bashrc),需重新加载配置或重启Shell生效:

# 1. 编辑配置文件
vim ~/.bashrc

# 2. 在文件末尾添加变量(无需export,.bashrc加载时会自动处理)
APP_ENV=development
DB_HOST=localhost

# 3. 重新加载配置(无需重启Shell)
source ~/.bashrc  # 或 . ~/.bashrc

# 4. 验证
echo $DB_HOST  # 输出:localhost

(3)系统级永久生效(所有用户)

需管理员权限,配置写入/etc/profile,对所有用户生效:

# 1. 编辑系统配置文件(需sudo)
sudo vim /etc/profile

# 2. 添加变量
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$PATH:$JAVA_HOME/bin  # 将Java路径追加到PATH

# 3. 重新加载配置(所有用户需重新登录生效)
source /etc/profile

# 4. 验证
echo $JAVA_HOME  # 输出:/usr/lib/jvm/java-11-openjdk-amd64
java -version    # 正常显示Java版本,说明PATH配置生效

注意:修改系统级配置文件时需谨慎,错误配置可能导致系统命令失效(如PATH设置错误)。建议先在终端测试命令,确认无误后再写入配置文件。

二、配置文件:让脚本“按需加载”配置

当脚本需要大量参数(如数据库账号、API密钥、路径配置)时,直接写死在脚本中会导致维护困难——修改配置需修改脚本本身,且无法适配多环境。此时,将配置单独放在配置文件中,让脚本“按需读取”,是更优雅的解决方案。

1. 配置文件的常见格式

Shell脚本常用的配置文件格式为“键值对”,简单易懂且易于解析,示例(app.conf):

# 这是注释行(以#开头)
# 数据库配置
DB_HOST=192.168.1.100
DB_PORT=3306
DB_USER=root
DB_PASS=123456  # 生产环境需避免明文存储,可结合加密工具

# 应用配置
APP_NAME="MyShellApp"
LOG_PATH="/var/log/myapp"
DEBUG=true  # 布尔值用true/false标记

2. 脚本读取配置文件的3种方法

(1)source命令加载(最简单)

source命令可将配置文件中的变量直接加载到当前Shell环境,脚本中可直接使用变量名调用,适用于信任的配置文件(无恶意代码):

#!/bin/bash
# 脚本名:load_config.sh

# 1. 检查配置文件是否存在
CONFIG_FILE="./app.conf"
if [ ! -f "$CONFIG_FILE" ]; then
    echo "错误:配置文件 $CONFIG_FILE 不存在!"
    exit 1  # 退出脚本,状态码1表示错误
fi

# 2. 加载配置文件(变量直接生效)
source "$CONFIG_FILE"

# 3. 使用配置变量
echo "应用名称:$APP_NAME"
echo "数据库地址:$DB_HOST:$DB_PORT"
echo "日志路径:$LOG_PATH"

# 4. 条件判断(基于配置)
if [ "$DEBUG" = "true" ]; then
    echo "调试模式已开启,日志将输出详细信息"
else
    echo "生产模式,日志仅记录错误信息"
fi

执行脚本:

bash load_config.sh
# 输出:
# 应用名称:MyShellApp
# 数据库地址:192.168.1.100:3306
# 日志路径:/var/log/myapp
# 调试模式已开启,日志将输出详细信息

(2)awk解析(适合复杂配置)

若配置文件包含注释、空行,或需要筛选特定字段,可使用awk工具解析,避免加载无用变量:

#!/bin/bash
# 脚本名:parse_config.sh

CONFIG_FILE="./app.conf"
if [ ! -f "$CONFIG_FILE" ]; then
    echo "错误:配置文件 $CONFIG_FILE 不存在!"
    exit 1
fi

# 使用awk提取键值对(忽略注释和空行)
# NF>0:非空行;$1!~/^#/:行首不是#(非注释)
DB_HOST=$(awk -F '=' '/^DB_HOST/ && NF>0 && $1!~/^#/ {gsub(/"/,"",$2); print $2}' "$CONFIG_FILE")
LOG_PATH=$(awk -F '=' '/^LOG_PATH/ && NF>0 && $1!~/^#/ {gsub(/"/,"",$2); print $2}' "$CONFIG_FILE")

# 输出解析结果
echo "解析到的数据库地址:$DB_HOST"
echo "解析到的日志路径:$LOG_PATH"

执行脚本:

bash parse_config.sh
# 输出:
# 解析到的数据库地址:192.168.1.100
# 解析到的日志路径:/var/log/myapp

(3)while循环逐行读取(灵活可控)

通过while read循环逐行处理配置文件,可自定义解析逻辑(如处理变量引用、多值配置):

#!/bin/bash
# 脚本名:read_config.sh

CONFIG_FILE="./app.conf"
if [ ! -f "$CONFIG_FILE" ]; then
    echo "错误:配置文件 $CONFIG_FILE 不存在!"
    exit 1
fi

# 逐行读取配置文件(IFS=保持行内空格,-r避免转义字符生效)
while IFS= read -r line; do
    # 跳过注释和空行
    [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
    
    # 分割键值对(等号前后允许空格)
    key=$(echo "$line" | awk -F '=' '{gsub(/[ \t]+/,"",$1); print $1}')
    value=$(echo "$line" | awk -F '=' '{gsub(/[ \t]+|"|\047/,"",$2); print $2}')  # 去除空格、引号
    
    # 将键值对设置为脚本局部变量(避免污染全局环境)
    declare "$key=$value"
done < "$CONFIG_FILE"

# 使用变量
echo "数据库用户:$DB_USER"
echo "调试模式:$DEBUG"

执行脚本:

bash read_config.sh
# 输出:
# 数据库用户:root
# 调试模式:true

3. 脚本修改配置文件(动态更新)

除了读取配置,脚本还可动态修改配置文件中的值(如通过脚本切换环境、更新密码),核心是使用sed工具替换文本:

#!/bin/bash
# 脚本名:update_config.sh

CONFIG_FILE="./app.conf"
TARGET_KEY="DB_PASS"
NEW_VALUE="abc67890"  # 新的数据库密码

# 检查配置项是否存在
if ! grep -q "^$TARGET_KEY=" "$CONFIG_FILE"; then
    echo "警告:配置项 $TARGET_KEY 不存在,将追加到配置文件"
    echo "$TARGET_KEY=$NEW_VALUE" >> "$CONFIG_FILE"
else
    # 替换配置项的值(sed:行首匹配TARGET_KEY=,替换等号后的内容)
    sed -i "s/^$TARGET_KEY=.*/$TARGET_KEY=$NEW_VALUE/" "$CONFIG_FILE"
    echo "已更新 $TARGET_KEY 的值为:$NEW_VALUE"
fi

# 验证修改结果
grep "^$TARGET_KEY=" "$CONFIG_FILE"

执行脚本:

bash update_config.sh
# 输出:
# 已更新 DB_PASS 的值为:abc67890
# DB_PASS=abc67890

注意sed -i在Linux(GNU sed)中直接修改文件,在macOS(BSD sed)中需加空参数(sed -i ''),跨平台脚本可使用sed -i.bak(生成备份文件,再删除备份)。

三、实战:多环境适配的部署脚本

结合环境变量与配置文件,我们编写一个支持“开发/测试/生产”三环境的应用部署脚本,实现“一套脚本,多环境复用”。

1. 目录结构

deploy/
├── deploy.sh          # 部署脚本
├── config/
│   ├── dev.conf       # 开发环境配置
│   ├── test.conf      # 测试环境配置
│   └── prod.conf      # 生产环境配置
└── logs/              # 日志目录

2. 配置文件示例(prod.conf)

# 生产环境配置
APP_PORT=8080
DB_HOST=prod-db.example.com
DB_PORT=3306
DB_USER=prod_user
LOG_PATH="./logs/prod.log"
DEPLOY_PATH="/opt/myapp"

3. 部署脚本(deploy.sh)

#!/bin/bash
set -e  # 脚本出错时立即退出(避免继续执行)

# 1. 检查环境变量(指定部署环境)
if [ -z "$APP_ENV" ]; then
    echo "请通过环境变量 APP_ENV 指定部署环境(dev/test/prod)"
    echo "示例:APP_ENV=prod bash deploy.sh"
    exit 1
fi

# 2. 加载对应环境的配置文件
CONFIG_FILE="./config/$APP_ENV.conf"
if [ ! -f "$CONFIG_FILE" ]; then
    echo "错误:环境 $APP_ENV 的配置文件 $CONFIG_FILE 不存在!"
    exit 1
fi
source "$CONFIG_FILE"
echo "=== 加载 $APP_ENV 环境配置完成 ==="

# 3. 环境检查(如生产环境需验证DB地址)
if [ "$APP_ENV" = "prod" ]; then
    echo "=== 生产环境前置检查 ==="
    # 检查数据库连接(需安装mysql-client)
    if ! mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p -e "SELECT 1" > /dev/null 2>&1; then
        echo "错误:无法连接生产数据库,请检查配置!"
        exit 1
    fi
    echo "数据库连接正常"
fi

# 4. 部署步骤(示例:创建目录、启动应用)
echo "=== 开始部署 $APP_NAME ==="
# 创建部署目录
mkdir -p "$DEPLOY_PATH" "$(dirname "$LOG_PATH")"
# 模拟应用启动(实际场景替换为真实启动命令)
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 应用启动成功,端口:$APP_PORT" >> "$LOG_PATH"
echo "部署完成!日志路径:$LOG_PATH"

# 5. 输出部署信息
echo -e "\n=== 部署信息汇总 ==="
echo "环境:$APP_ENV"
echo "应用端口:$APP_PORT"
echo "部署路径:$DEPLOY_PATH"
echo "数据库地址:$DB_HOST:$DB_PORT"

4. 执行部署脚本

# 部署生产环境(通过环境变量指定环境)
APP_ENV=prod bash deploy.sh

# 输出:
# === 加载 prod 环境配置完成 ===
# === 生产环境前置检查 ===
# Enter password: (输入数据库密码)
# 数据库连接正常
# === 开始部署 MyShellApp ===
# 部署完成!日志路径:./logs/prod.log
# 
# === 部署信息汇总 ===
# 环境:prod
# 应用端口:8080
# 部署路径:/opt/myapp
# 数据库地址:prod-db.example.com:3306

通过环境变量APP_ENV切换环境,脚本自动加载对应配置,实现了“无修改适配多环境”,极大降低了维护成本。

四、避坑指南与最佳实践

总结

环境变量是Shell脚本的“全局参数池”,配置文件是“场景化配置库”,两者结合是实现脚本灵活性的核心。从临时调试的变量设置,到多环境部署的配置加载,掌握这些技能能让你的Shell脚本从“一次性工具”升级为“可复用、可维护的工程化解决方案”。

到此这篇关于Shell脚本实现环境变量与配置文件应用指南的文章就介绍到这了,更多相关Shell脚本环境变量与配置文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文