为何Bash扩展通配符匹配在bash/source及交互模式下结果不同?
Bash交互与非交互模式下extglob语法差异问题
问题描述
我有一段脚本:
case 11.2 in +([0-9])?(.+([0-9]))) echo aa;; *) echo bb;; esac
使用source test.sh执行时输出aa,但使用bash test.sh执行时出现语法错误,错误信息如下:
test.sh: line 1: syntax error near unexpected token `(' test.sh: line 1: `case 11.2 in +([0-9])?(.+([0-9]))) echo aa;; *) echo bb;; esac'
使用bash -i可作为临时解决方法,但想知道为什么交互模式与非交互模式下会有这种差异?
原因解析
核心问题出在**extglob(扩展通配符)**选项的默认启用状态:
source test.sh是在当前shell进程中执行,而日常使用的交互式shell默认已经开启了extglob,所以脚本里的+([0-9])这类扩展通配符语法能被识别,正常匹配并输出aa。bash test.sh会启动一个新的非交互式bash进程,这种模式下extglob默认是关闭的,bash无法解析+()这类扩展语法,直接抛出语法错误。bash -i会启动交互式bash进程,此时extglob默认开启,所以脚本能正常运行。
永久解决方法
不需要依赖交互模式,有两种可靠方式让脚本在非交互模式下正常工作:
- 在脚本开头显式启用
extglob:
shopt -s extglob case 11.2 in +([0-9])?(.+([0-9]))) echo aa;; *) echo bb;; esac
- 执行脚本时通过参数指定启用
extglob:
bash -O extglob test.sh
内容的提问来源于stack exchange,提问作者Steven Yang
相关产品推荐
相关产品推荐

