Bash =〜在cmd提示符OS X处丢失BASH_REMATCH内容

daw*_*awg 3 macos bash

假设我有一个(愚蠢的例子)脚本:

#!/bin/bash
st="one two three"
[[ $st =~ ^([[:alpha:]]+)[[:space:]]([[:alpha:]]+)[[:space:]]([[:alpha:]]+) ]]
for i in "${BASH_REMATCH[@]}"
do
    echo "$i"
done    
Run Code Online (Sandbox Code Playgroud)

它按预期工作 - 它打印:

one two three
one
two
three
Run Code Online (Sandbox Code Playgroud)

这是每个匹配组的总体匹配.但是,如果我去shell并输入:

$ st="one two three"
$ [[ $st =~ ^([[:alpha:]]+)[[:space:]]([[:alpha:]]+)[[:space:]]([[:alpha:]]+) ]]
$ for i in "${BASH_REMATCH[@]}"
> do
>    echo "$i"
> done
Run Code Online (Sandbox Code Playgroud)

它打印:

w
Run Code Online (Sandbox Code Playgroud)

如果我做

$ [[ $st =~ ^([[:alpha:]]+)[[:space:]]([[:alpha:]]+)[[:space:]]([[:alpha:]]+) ]] && arr=( "${BASH_REMATCH[@]}" )
Run Code Online (Sandbox Code Playgroud)

我然后可以通过副本循环BASH_REMATCHarr显示出比赛的作品确定.但是BASH_REMATCH在Bash 3.2上的交互式shell使用中似乎发生了一些事情.在成功比赛之后.

这是3.2.57(1)-releasemacOS Sierra 10.12.1 的默认设置

如果我启动Bash 4.4,一切正常.

想法?


编辑

戈登戴维斯是正确的:它与Apple实用程序有关"${BASH_REMATCH[@]}",用于显示提示.

易于演示:

$ cd ~
$ pwd && echo "${BASH_REMATCH[@]}"
/Users/andrew
w
$ cd /tmp
$ pwd && echo "${BASH_REMATCH[@]}"
/tmp
p
Run Code Online (Sandbox Code Playgroud)

然后,如果我运行没有rc文件的Apple的bash :

$ /bin/bash  --norc
bash-3.2$ pwd && echo "${BASH_REMATCH[@]}"
/tmp

bash-3.2$ 
Run Code Online (Sandbox Code Playgroud)

(那里有一个空白行"${BASH_REMATCH[@]}"......)

Gor*_*son 7

这是因为Apple的默认bash init文件具有定义提示的奇特函数,并且每次需要显示提示时它都会重新计算它,并且该函数使用=~并因此替换以前的内容BASH_REMATCH.请参阅update_terminal_cwd/ etc/bashrc_Apple_Terminal中的定义(由/ etc/bashrc提供).

如果这会给你带来麻烦,我认为用函数取消定义函数是安全的unset PROMPT_COMMAND(保留了函数,但是没有使用它).

BTW,BASH_REMATCH由于函数逐个字符地逐步遍历您的工作目录,因此将其设置为"w",并对其进行URL编码."w"显然是工作目录中的最后一个字符.

编辑:看看这个函数,它实际上并没有对提示做任何事情; 它设置终端窗口标题栏的文件夹部分.如果您取消设置PROMPT_COMMAND,它将停止更新窗口标题.