如何在Bash脚本中延迟name变量展开以实现循环内正确引用
Bash脚本延迟变量展开的解决方案
问题分析
你的脚本无法正确展开name变量,核心原因有两点:
- 对
${name}添加了转义符\,导致echo输出的是字面量${name}而非变量的实际值 - 使用
$(...)子shell构造路径会触发不必要的字符串拆分,且无法让name在函数调用的上下文正确展开
最优解决方案
直接利用Bash的路径通配(glob)特性,在循环中直接构造匹配模式,让name在函数调用时的上下文展开:
name='*' curate() { # 启用nullglob:无匹配文件时不生成空条目,避免无效路径输出 shopt -s nullglob # 直接构造匹配路径,name变量会在调用时自动展开 for e in "/home/me/Downloads/${name}.$1"; do echo "$e" done # 关闭nullglob,恢复默认行为 shopt -u nullglob } curate c name=foo curate c
方案说明
- 当
name='*'时,/home/me/Downloads/${name}.c会被展开为所有.c后缀的文件 - 当
name='foo'时,会精确匹配/home/me/Downloads/foo.c(若文件存在) nullglob选项用于避免无匹配文件时,将通配符本身当作文件名处理
备选方案(若需临时修改HOME)
如果必须在子shell中临时修改HOME变量,需移除${name}的转义,让子shell直接展开变量:
name='*' curate() { local e= # 移除${name}的转义,让子shell直接展开变量 for e in $(export HOME='/home/me'; echo "$HOME/Downloads/${name}.$1") do [ -e "$e" ] && echo "$e" done } curate c name=foo curate c
注意:此方案存在文件名含空格时拆分错误的风险,优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者user17227456
相关产品推荐
相关产品推荐

