有一个脚本:
#!/bin/bash
s='1 2, 3 4,'
s0="$(echo ${s//,/ }|tr -s ' ')"
echo "s0: $s0"
d="'${s0//+([[:space:]])/"' '"}'"
echo "d: $d"
当我运行此脚本时,输出是:
$ ./test.sh
s0: 1 2 3 4
d: '1 2 3 4'
当我在 bash 提示符下一一运行命令时,$d
变量正确显示:
$ s='1 2, 3 4,'
$ s0="$(echo ${s//,/ }|tr -s ' ')"
$ echo "s0: $s0"
s0: 1 2 3 4
$ d="'${s0//+([[:space:]])/"' '"}'"
$ echo "d: $d"
d: '1' '2' '3' '4'
$
命令在 bash 中运行:
$ type bash
bash is /bin/bash
$ echo $0
-bash
为什么$d
脚本运行期间设置为'1 2 3 4'
而不是预期的'1' '2' '3' '4'
?
答案1
默认情况下,Bash 中未启用扩展的 glob +(...)
,您需要shopt -s extglob
在脚本中显式使用才能启用它们。
您的交互式 shell 可能已extglob
启用(在某些启动文件中),因此当您在命令行上尝试替换命令时,它会按预期工作。但在脚本中,大多数启动文件不会被读取,extglob
处于禁用状态,并且加号和括号被视为文字字符。字符类在两者中的工作方式相同,因此关闭+( )
时类似的内容会匹配模式。extglob
在这里,模式与任何内容都不匹配,没有替换,唯一的更改d
是在扩展周围添加的单引号${s0//...}
。