Bash脚本如何正确解析传参中脚本启动后才赋值的变量
问题原因
Bash 对命令的解析执行顺序是先完成当前shell环境下的变量展开,再启动执行目标命令/脚本。
你在命令行写bash test.sh https://example/$TARGETARCH时,参数里的$TARGETARCH会被你当前敲命令的父shell提前展开:这时候脚本还没启动,脚本里写的TARGETARCH=amd64根本没执行,父shell环境里也没有定义TARGETARCH变量,展开后参数就变成了https://example/,传给脚本后自然输出不符合预期。
实现方案
根据你的使用场景选对应方法即可:
方案1:变量在脚本内部赋值(匹配你当前的脚本写法)
如果TARGETARCH的值必须在脚本运行后才能确定,调用脚本时要禁止父shell提前展开参数里的变量,把参数作为模板传入脚本,再在脚本内部完成变量替换。
- 调用脚本时转义
$符号,或者用单引号包裹参数,让父shell不要解析$TARGETARCH:
# 写法1:单引号包裹,单引号内的变量不会被展开 bash test.sh 'https://example/$TARGETARCH' # 写法2:用反斜杠转义$符号 bash test.sh https://example/\$TARGETARCH
- 修改脚本内容,在变量赋值完成后,对传入的参数模板做展开:
#!/bin/bash TARGETARCH=amd64 # 对传入的模板参数做变量展开,注意:参数不可信时不要用eval,存在命令注入风险 eval "full_url=\"$1\"" echo "$full_url"
执行后就会输出预期的https://example/amd64。
如果觉得eval有安全风险,也可以用envsubst做更安全的模板替换:
#!/bin/bash TARGETARCH=amd64 full_url=$(echo "$1" | TARGETARCH=$TARGETARCH envsubst '${TARGETARCH}') echo "$full_url"
方案2:变量在调用前赋值(无需修改脚本原有echo逻辑)
如果你可以在调用脚本前就确定TARGETARCH的值,可以直接在调用脚本前给当前shell/命令环境赋值,让父shell提前完成参数替换,脚本拿到的直接就是完整的目标地址:
# 赋值写在命令前,仅对当前执行的test.sh生效,不会污染全局shell环境 TARGETARCH=amd64 bash test.sh https://example/$TARGETARCH
这种写法不需要修改你原来的test.sh内容,执行后同样会输出https://example/amd64。
内容的提问来源于stack exchange,提问作者Danil
相关产品推荐
相关产品推荐

