Bash 参数扩展“${var##pat}”在脚本中的行为不同于 shell

Bash param expansion "${var##pat}" behaves differently in script than in shell

我正在尝试在脚本中使用非常基本的 Bash 参数扩展,但它不起作用;不过,当我在我的交互式 shell 中 运行 它时它工作正常。这是小测试脚本:

<~> $ cat /tmp/foo
#!/usr/bin/env bash

foo="bar 1.2.3"
echo $foo
echo ${foo##*([^0-9])}
echo ${foo/a/-}

当我 运行 脚本时,第一个参数扩展 (${foo##*([^0-9])}) 不起作用,但第二个 (${foo/a/-}) 可以:

<~> $ /tmp/foo
bar 1.2.3
bar 1.2.3
b-r 1.2.3

如果我改用它(运行在我当前的 shell 中使用它),它会按预期工作:

<~> $ . /tmp/foo
bar 1.2.3
1.2.3
b-r 1.2.3

怀疑实际 shell 与 运行、shell 版本或设置存在差异,我扩展了脚本:

<~> $ cat /tmp/foo
#!/usr/bin/env bash

echo "SHELL: $SHELL"
echo "VERSION: $BASH_VERSION"
echo

set -o
echo

foo="bar 1.2.3"
echo $foo
echo ${foo##*([^0-9])}
echo ${foo/a/-}

现在我明白了:

<~> $ /tmp/foo
SHELL: /opt/local/bin/bash
VERSION: 5.1.16(1)-release

allexport       off
braceexpand     on
emacs           off
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      off
history         off
ignoreeof       off
interactive-comments    on
keyword         off
monitor         off
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off

bar 1.2.3
bar 1.2.3
b-r 1.2.3

看起来没有什么不妥,运行对两者进行比较并比较输出没有任何意义:

<~> $ diff <(/tmp/foo) <(. /tmp/foo)
6c6
< emacs             off
---
> emacs             on
11,12c11,12
< histexpand        off
< history           off
---
> histexpand        on
> history           on
16c16
< monitor           off
---
> monitor           on
33c33
< bar 1.2.3
---
> 1.2.3

关于我在这里遗漏的任何想法(除了线索,'natch)?谢谢!

附录

只是为了从下面接受的答案中得出完整的图片,在脚本输出中添加 shopt 显示了脚本版本和交互式 shell 版本之间的这些额外差异:

52c52
< expand_aliases    off
---
> expand_aliases    on
54c54
< extglob           off
---
> extglob           on
61c61
< histappend        off
---
> histappend        on
64c64
< hostcomplete      on
---
> hostcomplete      off
72c72
< login_shell       off
---
> login_shell       on

确实缺少选项 (extglob)。

您需要添加

shopt -s extglob

添加到脚本以启用 *(pattern-list) 扩展通配。我怀疑您在 .bashrc.

的交互式 shell 中启用了此功能