Shell脚本变量取值优先级疑问及内部变量强制调用方法咨询
现象原理
该问题的核心成因是Shell的变量展开时机早于脚本执行时机:
- 当你使用双引号包裹
"echo $STRING"作为参数时,执行命令的父Shell会先对双引号内的$STRING做变量替换,替换为当前父Shell环境中STRING的值not_my_string,最终传递给script.sh的第一个参数实际是echo not_my_string。 - 脚本执行时拿到的参数已经完成了变量替换,直接执行
echo not_my_string自然输出外部的变量值,完全不会用到脚本内部定义的STRING变量。
强制输出脚本内部STRING值的方法
只要保证传递给脚本的参数中的$STRING不会被父Shell提前展开即可,常用有两种方案:
- 方案1:使用单引号包裹参数。单引号在Shell规则中会关闭内部所有特殊字符的转义、替换功能,父Shell不会处理单引号内的
$符号:
调整后命令:./script.sh 'echo $STRING' - 方案2:双引号内转义
$符号。如果必须使用双引号(比如参数中同时需要插入其他需要父Shell提前展开的变量),可以用反斜杠转义$,阻止父Shell展开当前变量:
调整后命令:./script.sh "echo \$STRING"
两种方案最终传递给脚本的参数都是原生的echo $STRING,脚本执行时会使用内部读取自my_string.txt的STRING值,输出this_is_my_string。
补充说明
如果需要进一步避免脚本内的变量被外部导出的同名环境变量覆盖,可以在脚本定义变量时添加readonly修饰:
#!/bin/bash readonly STRING=$(cat my_string.txt) ${1}
该配置会让脚本内的STRING变量不可被修改,也不会被外部传入的同名环境变量覆盖,进一步保证取值符合预期。
内容的提问来源于stack exchange,提问作者Nachdougs
相关产品推荐
相关产品推荐

