bash 脚本产生的输出与在 bash 提示符下运行命令时产生的输出不同

bash 脚本产生的输出与在 bash 提示符下运行命令时产生的输出不同

有一个脚本:

#!/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//...}

相关内容