ERR陷阱中双引号路径名在命令替换中意外展开的问题
问题分析与解决
原因
你碰到的问题本质是Bash对陷阱命令的二次解析行为:
当你用trap 'echo "*.sh"' ERR设置陷阱时,命令字符串echo "*.sh"会被存储起来。在主shell中触发陷阱时,双引号能正常阻止*.sh的路径扩展;但在命令替换的子shell中触发陷阱时,Bash会对这个命令字符串重新解析,原本的双引号被当作语法符号剥离,*.sh失去引号保护,被扩展为当前目录下的.sh文件(即1.sh)。
解决方法
要让*.sh始终以字面量输出,需用单引号嵌套包裹它,确保路径扩展完全被阻止。有两种常用写法:
写法1:单引号嵌套
trap 'echo '\''*.sh'\''' ERR
写法2:双引号包裹单引号
trap "echo '*'" ERR
修改后的完整脚本:
#!/usr/bin/env bash trap "echo '*'" ERR set -E echo *.sh false echo $(false)
执行后会得到你预期的输出:
1.sh *.sh *.sh
针对你提到的shopt -s failglob导致崩溃的问题,修改后的陷阱命令不会触发路径扩展,因此即使启用failglob,也不会因匹配不到文件而报错退出。
内容的提问来源于stack exchange,提问作者ynn
相关产品推荐
相关产品推荐

