Shell 脚本中使用环境变量 新手超详细教程这个简单写一下环境变量和 Shell 脚本结合的核心逻辑是「进程继承规则」Linux 中每个程序都是一个进程父进程的环境变量会自动传递给它启动的所有子进程。脚本默认以「子 Shell 进程」的方式运行因此它天然能继承当前终端的所有环境变量但反过来脚本内部定义的变量默认不会影响外部的父终端子进程结束变量就销毁了。下面我们从「基础读取 → 传参方式 → 反向生效 → 实战场景 → 避坑指南」逐层讲解每个知识点都配可运行的例子和逐行拆解同时结合你嵌入式开发的场景给出实用案例。一、基础用法脚本中直接读取环境变量这是最简单的用法环境变量不需要在脚本里重新定义直接用$变量名就能读取不管是系统自带的还是你在终端里提前导出的都能直接用。1. 读取系统内置的环境变量系统预设的环境变量HOME、USER、PATH、PWD等所有脚本都能直接读取不需要任何额外操作。示例脚本read_env.sh#!/bin/bash # 功能读取并打印系统内置环境变量 echo 系统环境信息 echo 当前登录用户$USER echo 用户家目录$HOME echo 当前所在路径$PWD echo 默认Shell解释器$SHELL echo 系统主机名$HOSTNAME echo 系统语言编码$LANG echo 运行与效果chmod x read_env.sh ./read_env.sh输出示例 系统环境信息 当前登录用户linuxlearn 用户家目录/home/linuxlearn 当前所在路径/home/linuxlearn/script 默认Shell解释器/bin/bash 系统主机名ubuntu 系统语言编码zh_CN.UTF-8 原理说明这些变量是启动终端时就存在的「全局环境变量」脚本作为终端启动的子进程自动继承了全部环境变量所以直接用$变量名就能拿到值。2. 读取用户自定义的环境变量你在终端里用export导出的自定义环境变量脚本也能直接读到。完整操作步骤先在终端定义并导出一个环境变量# 导出自定义项目路径变量 export PROJECT_DIR/home/linuxlearn/ok62xx_project export BOARD_MODELOK6254写脚本read_custom_env.sh直接读取#!/bin/bash echo 项目根目录$PROJECT_DIR echo 开发板型号$BOARD_MODEL运行脚本./read_custom_env.sh输出项目根目录/home/linuxlearn/ok62xx_project 开发板型号OK6254✅ 核心结论只要是父终端里export过的环境变量子脚本里直接用、不用重定义。二、三种方式给脚本传递自定义环境变量除了提前在终端 export还有三种常用的传参方式适用不同场景新手都要掌握。方式 1运行脚本时「临时指定」最灵活调试常用可以在运行脚本的命令前临时加上环境变量只对本次脚本运行生效不会影响当前终端的环境。语法变量1值 变量2值 ./脚本名.sh实战例子写一个备份脚本backup.sh备份路径和保留天数通过环境变量传入#!/bin/bash # 备份脚本通过环境变量接收配置 echo 备份源目录$BACKUP_SRC echo 保留天数$KEEP_DAYS echo 开始执行备份...运行时临时指定参数BACKUP_SRC/data/project KEEP_DAYS7 ./backup.sh输出备份源目录/data/project 保留天数7 开始执行备份...适用场景临时调试脚本想改参数又不想修改脚本内容同一个脚本不同场景传不同配置不用写多份不污染当前终端的全局环境用完就消失方式 2终端先 export 全局导出长期生效多个脚本复用就是上面基础用法里的方式先在终端export变量后面运行的所有脚本都能读到适合一段时间内都要用的变量。# 终端里先导出一次 export CROSS_COMPILEarm-linux-gnueabihf- export ARCHarm # 后面运行的所有脚本都能直接用这两个变量 ./build.sh ./deploy.sh适用场景同一会话里多个脚本都要用同一个变量嵌入式开发里设置编译环境一次设置全程有效方式 3source运行脚本双向互通配置脚本专用默认运行脚本会开一个「子进程」变量是单向继承的父传子可以子传父不行。 如果用source简写.运行脚本不会开子进程直接在当前终端 Shell 里执行脚本代码变量是双向互通的。对比演示写一个脚本set_var.sh#!/bin/bash export TEST_VAR我是脚本里的环境变量 echo 脚本内部打印$TEST_VAR普通方式运行子进程./set_var.sh echo 脚本外打印$TEST_VAR # 输出空子进程的变量传不出来source 方式运行同进程source set_var.sh # 或者简写 . set_var.sh echo 脚本外打印$TEST_VAR # 能正常输出值适用场景环境配置类脚本比如设置交叉编译环境、加载项目环境变量必须 source 才能让配置在当前终端生效脚本里修改 PATH、LD_LIBRARY_PATH 等需要对当前终端生效的场景三、重点实战嵌入式开发环境配置脚本这是你日常开发最常用的场景写一个环境配置脚本一键设置好交叉编译工具链的 PATH、目标架构、编译器前缀source 之后就能直接编译。示例脚本ok62xx_env.sh#!/bin/bash # OK62xx 交叉编译环境配置脚本 # 使用方法source ok62xx_env.sh # 1. 交叉编译器安装路径 TOOLCHAIN_PATH/opt/gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf/bin # 2. 把编译器目录加入 PATH export PATH$TOOLCHAIN_PATH:$PATH # 3. 设置内核编译用的架构和交叉编译器前缀 export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf- # 4. 设置动态库搜索路径可选 export LD_LIBRARY_PATH/opt/ok62xx_lib:$LD_LIBRARY_PATH echo ✅ OK62xx 交叉编译环境已加载 echo 架构$ARCH echo 编译器前缀$CROSS_COMPILE echo PATH 已更新使用方法# 必须用 source 运行不然 PATH 不会在当前终端生效 source ok62xx_env.sh验证# 查看编译器版本能正常输出版本就是配置成功 arm-linux-gnueabihf-gcc -v 这是嵌入式开发的标准操作每个项目一个环境脚本需要的时候 source 一下不会和其他项目的编译环境冲突。四、进阶用法环境变量做逻辑判断环境变量还可以用来控制脚本的执行逻辑实现「一个脚本多种运行模式」。示例根据环境变量控制日志级别#!/bin/bash # 通过 LOG_LEVEL 环境变量控制日志输出 # 如果没设置LOG_LEVEL默认是info LOG_LEVEL${LOG_LEVEL:-info} echo 当前日志级别$LOG_LEVEL if [ $LOG_LEVEL debug ] then echo [DEBUG] 调试信息正在加载配置... fi echo [INFO] 程序启动中... if [ $LOG_LEVEL debug ] then echo [DEBUG] 初始化完成耗时0.2s fi运行效果默认运行./test_log.sh→ 只输出 info 级别的日志调试模式运行LOG_LEVELdebug ./test_log.sh→ 输出详细调试日志好处不用修改脚本代码通过环境变量就能切换运行模式非常灵活。五、新手必踩坑与避坑指南坑 1脚本里 export 了变量外面看不到原因脚本默认在子 Shell 进程里运行子进程的环境变量不会反向传给父终端脚本结束进程销毁变量就没了。解决需要对当前终端生效的配置脚本必须用source/.运行。坑 2脚本里读不到我定义的变量原因你只定义了普通 Shell 变量没有export导出成环境变量子进程继承不到。对比# 普通变量子脚本读不到 A测试 # 环境变量子脚本能读到 export B测试坑 3路径变量有空格脚本报错原因环境变量的值包含空格时直接用$VAR会被拆成多个参数。解决引用变量时一定要加双引号$VAR。# ❌ 错误路径有空格就报错 cd $PROJECT_PATH # ✅ 正确加双引号保证整体作为一个参数 cd $PROJECT_PATH坑 4环境变量名用小写约定俗成环境变量全大写比如PATH、HOME、PROJECT_DIR脚本内的普通变量用小写方便区分。不是语法强制但行业通用规范建议遵守。坑 5修改 PATH 后不生效脚本里修改了 PATH关掉终端再打开就没了 → 要永久生效就写到~/.bashrc里。脚本里改了 PATH当前终端没变化 → 子进程修改不影响父终端source 运行脚本才行。
Linux系统基础15:Shell 脚本中使用环境变量
Shell 脚本中使用环境变量 新手超详细教程这个简单写一下环境变量和 Shell 脚本结合的核心逻辑是「进程继承规则」Linux 中每个程序都是一个进程父进程的环境变量会自动传递给它启动的所有子进程。脚本默认以「子 Shell 进程」的方式运行因此它天然能继承当前终端的所有环境变量但反过来脚本内部定义的变量默认不会影响外部的父终端子进程结束变量就销毁了。下面我们从「基础读取 → 传参方式 → 反向生效 → 实战场景 → 避坑指南」逐层讲解每个知识点都配可运行的例子和逐行拆解同时结合你嵌入式开发的场景给出实用案例。一、基础用法脚本中直接读取环境变量这是最简单的用法环境变量不需要在脚本里重新定义直接用$变量名就能读取不管是系统自带的还是你在终端里提前导出的都能直接用。1. 读取系统内置的环境变量系统预设的环境变量HOME、USER、PATH、PWD等所有脚本都能直接读取不需要任何额外操作。示例脚本read_env.sh#!/bin/bash # 功能读取并打印系统内置环境变量 echo 系统环境信息 echo 当前登录用户$USER echo 用户家目录$HOME echo 当前所在路径$PWD echo 默认Shell解释器$SHELL echo 系统主机名$HOSTNAME echo 系统语言编码$LANG echo 运行与效果chmod x read_env.sh ./read_env.sh输出示例 系统环境信息 当前登录用户linuxlearn 用户家目录/home/linuxlearn 当前所在路径/home/linuxlearn/script 默认Shell解释器/bin/bash 系统主机名ubuntu 系统语言编码zh_CN.UTF-8 原理说明这些变量是启动终端时就存在的「全局环境变量」脚本作为终端启动的子进程自动继承了全部环境变量所以直接用$变量名就能拿到值。2. 读取用户自定义的环境变量你在终端里用export导出的自定义环境变量脚本也能直接读到。完整操作步骤先在终端定义并导出一个环境变量# 导出自定义项目路径变量 export PROJECT_DIR/home/linuxlearn/ok62xx_project export BOARD_MODELOK6254写脚本read_custom_env.sh直接读取#!/bin/bash echo 项目根目录$PROJECT_DIR echo 开发板型号$BOARD_MODEL运行脚本./read_custom_env.sh输出项目根目录/home/linuxlearn/ok62xx_project 开发板型号OK6254✅ 核心结论只要是父终端里export过的环境变量子脚本里直接用、不用重定义。二、三种方式给脚本传递自定义环境变量除了提前在终端 export还有三种常用的传参方式适用不同场景新手都要掌握。方式 1运行脚本时「临时指定」最灵活调试常用可以在运行脚本的命令前临时加上环境变量只对本次脚本运行生效不会影响当前终端的环境。语法变量1值 变量2值 ./脚本名.sh实战例子写一个备份脚本backup.sh备份路径和保留天数通过环境变量传入#!/bin/bash # 备份脚本通过环境变量接收配置 echo 备份源目录$BACKUP_SRC echo 保留天数$KEEP_DAYS echo 开始执行备份...运行时临时指定参数BACKUP_SRC/data/project KEEP_DAYS7 ./backup.sh输出备份源目录/data/project 保留天数7 开始执行备份...适用场景临时调试脚本想改参数又不想修改脚本内容同一个脚本不同场景传不同配置不用写多份不污染当前终端的全局环境用完就消失方式 2终端先 export 全局导出长期生效多个脚本复用就是上面基础用法里的方式先在终端export变量后面运行的所有脚本都能读到适合一段时间内都要用的变量。# 终端里先导出一次 export CROSS_COMPILEarm-linux-gnueabihf- export ARCHarm # 后面运行的所有脚本都能直接用这两个变量 ./build.sh ./deploy.sh适用场景同一会话里多个脚本都要用同一个变量嵌入式开发里设置编译环境一次设置全程有效方式 3source运行脚本双向互通配置脚本专用默认运行脚本会开一个「子进程」变量是单向继承的父传子可以子传父不行。 如果用source简写.运行脚本不会开子进程直接在当前终端 Shell 里执行脚本代码变量是双向互通的。对比演示写一个脚本set_var.sh#!/bin/bash export TEST_VAR我是脚本里的环境变量 echo 脚本内部打印$TEST_VAR普通方式运行子进程./set_var.sh echo 脚本外打印$TEST_VAR # 输出空子进程的变量传不出来source 方式运行同进程source set_var.sh # 或者简写 . set_var.sh echo 脚本外打印$TEST_VAR # 能正常输出值适用场景环境配置类脚本比如设置交叉编译环境、加载项目环境变量必须 source 才能让配置在当前终端生效脚本里修改 PATH、LD_LIBRARY_PATH 等需要对当前终端生效的场景三、重点实战嵌入式开发环境配置脚本这是你日常开发最常用的场景写一个环境配置脚本一键设置好交叉编译工具链的 PATH、目标架构、编译器前缀source 之后就能直接编译。示例脚本ok62xx_env.sh#!/bin/bash # OK62xx 交叉编译环境配置脚本 # 使用方法source ok62xx_env.sh # 1. 交叉编译器安装路径 TOOLCHAIN_PATH/opt/gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf/bin # 2. 把编译器目录加入 PATH export PATH$TOOLCHAIN_PATH:$PATH # 3. 设置内核编译用的架构和交叉编译器前缀 export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf- # 4. 设置动态库搜索路径可选 export LD_LIBRARY_PATH/opt/ok62xx_lib:$LD_LIBRARY_PATH echo ✅ OK62xx 交叉编译环境已加载 echo 架构$ARCH echo 编译器前缀$CROSS_COMPILE echo PATH 已更新使用方法# 必须用 source 运行不然 PATH 不会在当前终端生效 source ok62xx_env.sh验证# 查看编译器版本能正常输出版本就是配置成功 arm-linux-gnueabihf-gcc -v 这是嵌入式开发的标准操作每个项目一个环境脚本需要的时候 source 一下不会和其他项目的编译环境冲突。四、进阶用法环境变量做逻辑判断环境变量还可以用来控制脚本的执行逻辑实现「一个脚本多种运行模式」。示例根据环境变量控制日志级别#!/bin/bash # 通过 LOG_LEVEL 环境变量控制日志输出 # 如果没设置LOG_LEVEL默认是info LOG_LEVEL${LOG_LEVEL:-info} echo 当前日志级别$LOG_LEVEL if [ $LOG_LEVEL debug ] then echo [DEBUG] 调试信息正在加载配置... fi echo [INFO] 程序启动中... if [ $LOG_LEVEL debug ] then echo [DEBUG] 初始化完成耗时0.2s fi运行效果默认运行./test_log.sh→ 只输出 info 级别的日志调试模式运行LOG_LEVELdebug ./test_log.sh→ 输出详细调试日志好处不用修改脚本代码通过环境变量就能切换运行模式非常灵活。五、新手必踩坑与避坑指南坑 1脚本里 export 了变量外面看不到原因脚本默认在子 Shell 进程里运行子进程的环境变量不会反向传给父终端脚本结束进程销毁变量就没了。解决需要对当前终端生效的配置脚本必须用source/.运行。坑 2脚本里读不到我定义的变量原因你只定义了普通 Shell 变量没有export导出成环境变量子进程继承不到。对比# 普通变量子脚本读不到 A测试 # 环境变量子脚本能读到 export B测试坑 3路径变量有空格脚本报错原因环境变量的值包含空格时直接用$VAR会被拆成多个参数。解决引用变量时一定要加双引号$VAR。# ❌ 错误路径有空格就报错 cd $PROJECT_PATH # ✅ 正确加双引号保证整体作为一个参数 cd $PROJECT_PATH坑 4环境变量名用小写约定俗成环境变量全大写比如PATH、HOME、PROJECT_DIR脚本内的普通变量用小写方便区分。不是语法强制但行业通用规范建议遵守。坑 5修改 PATH 后不生效脚本里修改了 PATH关掉终端再打开就没了 → 要永久生效就写到~/.bashrc里。脚本里改了 PATH当前终端没变化 → 子进程修改不影响父终端source 运行脚本才行。