Bash脚本中环境变量unset及生效异常问题求助
问题:脚本中设置的环境变量无法在当前Shell会话中生效
我在Windows的Git Bash里写了两段脚本,遇到了环境变量无法在当前会话留存的问题:
1. AWS凭证处理脚本问题
脚本开头为#!/usr/bin/env sh,内容如下:
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN export AWS_ACCESS_KEY_ID=$(echo $OUTPUT_ROLE | jq -r '.Credentials.AccessKeyId');\ export AWS_SECRET_ACCESS_KEY=$(echo $OUTPUT_ROLE | jq -r '.Credentials.SecretAccessKey');\ export AWS_SESSION_TOKEN=$(echo $OUTPUT_ROLE | jq -r '.Credentials.SessionToken'); echo "AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID" echo "AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY" echo "AWS_SESSION_TOKEN: $AWS_SESSION_TOKEN"
执行后控制台能正确输出变量值:
AWS_ACCESS_KEY_ID: <value> AWS_SECRET_ACCESS_KEY: <value> AWS_SESSION_TOKEN: <value>
但在当前Git Bash会话里直接执行echo $AWS_ACCESS_KEY_ID,变量值为空,连unset操作好像也没影响当前会话的变量。我试过./script.sh、source script.sh、bash script.sh三种执行方式,结果都一样。
2. 测试脚本问题
测试脚本example1.sh内容:
var="Hello" echo "start:$var" # Delete the var unset var echo "final:$var" var="new" echo "new:$var"
执行./example1.sh后输出:
start:Hello final: new:new
但执行完脚本后在控制台直接echo $var,结果还是空,就算把脚本开头改成#!/usr/bin/env bash也没用。
解决方法
核心原因是脚本默认在子Shell中执行,子Shell里的变量、unset操作都不会影响父Shell(你当前的Git Bash会话)。
1. 正确使用source或.命令加载脚本
你说试过source script.sh但没效果,大概率是操作细节出了问题:
- 必须指定正确的脚本路径:如果脚本在当前目录,要写
source ./script.sh(不能只写source script.sh,除非脚本在系统PATH目录下) - 绝对不要用
bash script.sh或者./script.sh执行,这两种方式会启动独立的子Shell,变量只在子Shell生命周期内生效,脚本结束后就会被销毁。
2. 适配Git Bash的特殊情况
Windows下的Git Bash偶尔会有路径解析的小问题,你可以试试用.命令替代source,两者功能完全一致:
. ./script.sh
3. 脚本优化建议
- 你的AWS脚本可以简化
jq调用,避免重复解析OUTPUT_ROLE:unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN # 一次性解析所有凭证,减少jq调用次数 eval "$(echo "$OUTPUT_ROLE" | jq -r '@sh "export AWS_ACCESS_KEY_ID=\(.Credentials.AccessKeyId) AWS_SECRET_ACCESS_KEY=\(.Credentials.SecretAccessKey) AWS_SESSION_TOKEN=\(.Credentials.SessionToken)"')" - 测试脚本用
source ./example1.sh执行后,再在控制台执行echo $var,就能看到new的值了,因为变量是直接在当前Shell会话中设置的。
内容的提问来源于stack exchange,提问作者rasilvap
相关产品推荐
相关产品推荐

