msysgit bash中的语法错误=〜运算符

时间:2013-03-19 20:45:14

标签: windows bash msysgit

我正在尝试为bash_profile添加一个函数:

function git-unpushed {
    brinfo=$(git branch -v | grep git-branch-name)
    if [[ $brinfo =~ ("[ahead "([[:digit:]]*)]) ]]
    then
        echo "(${BASH_REMATCH[2]})"
    fi
}

但是我收到以下错误:

  

bash:条件二元运算符expected`

     

bash:=~'附近的语法错误

根据我的发现,“equals tilde”运算符(=~)在bash中评估为正则表达式。

为什么=~会抛出错误?

更新:这是手动输入的截图(这是运行sh.exe):

Screenshot of equals tilde (=~) operator failing

4 个答案:

答案 0 :(得分:26)

我在Windows上的Git安装上遇到了与Bash 3.1.0相同的错误。最终我改为:

if echo $var | grep -E 'regexp' > /dev/null
then
  ...
fi

答案 1 :(得分:13)

根据https://groups.google.com/forum/#!topic/msysgit/yPh85MPDyfE,这是因为msys没有随bash一起发布libregex。据说如果你编译/找到一个msys构建的libregex,并把它放在库路径中,=~就可以正常工作了。

答案 2 :(得分:7)

2015年更新:msysgit现已过时 您应该使用 git-for-windows 附带的bash 正如this answer中所提到的,它使用了更新的bash(4.3+),=~语法将起作用。


原始答案(2013年3月)

使用msysgit打包的bash可能太旧而无法完全支持此运算符 与未加引号正则表达式进行比较肯定太旧了,如" Bash, version 3"和" How do I use regular expressions in bash scripts?":

  

自Bash版本3.2起,表达式不再引用。

实际上,mklement0在评论中提及:

  

=~是在bash 3.0中引入的,并且始终支持RHS上的未加引号的令牌   高达3.1.x,引用的令牌与未引用的令牌相同:两者都被解释为正则表达式。
  3.2中的变化是引用的令牌(或令牌的引用子串)现在被视为文字

但我试过引号(在最新的msysgit 1.8.1.2中),它仍然失败:

vonc@voncvb /
$ /bin/bash --version
GNU bash, version 3.1.0(1)-release (i686-pc-msys)
Copyright (C) 2005 Free Software Foundation, Inc.
vonc@voncvb /
$ variable="This is a fine mess."
vonc@voncvb /
$ echo "$variable"
This is a fine mess.
vonc@voncvb /
$ if [[ "$variable" =~ T.........fin*es* ]] ; then echo "ok" ; fi
bash: conditional binary operator expected
bash: syntax error near `=~'
vonc@voncvb /
$ if [[ "$variable" =~ "T.........fin*es*" ]] ; then echo "ok" ; fi
bash: conditional binary operator expected
bash: syntax error near `=~'
vonc@voncvb /

答案 3 :(得分:1)

这是一个支持提取匹配字符串的解决方案。如果bash不支持operator =〜,则使用sed命令(与msysgit一起安装)

if eval "[[ a =~ a ]]" 2>/dev/null; then
    regexMatch() { # (string, regex)
        eval "[[ \$1 =~ \$2 ]]"
        return $?
    }
elif command -v /bin/sed >/dev/null 2>&1; then
    regexMatch() { # (string, regex)
        local string=$1
        if [[ ${2: -1} = $ ]]; then
            local regex="(${2%$})()()()()()()()()$"
        else
            local regex="($2)()()()()()()()().*"
        fi
        regex=${regex//\//\\/}
        local replacement="\1\n\2\n\3\n\4\n\5\n\6\n\7\n\8\n\9\n"
        local OLD_IFS=$IFS
        IFS=$'\n'
        BASH_REMATCH=($(echo "$string" | /bin/sed -rn "s/$regex/$replacement/p" | while read -r; do echo "${REPLY}"; done))
        IFS=$OLD_IFS
        [[ $BASH_REMATCH ]] && return 0 || return 1
    }
else
    error "your Bash shell does not support regular expressions"
fi

用法示例:

if regexMatch "username@host.domain" "(.+)@(.+)"; then
    echo ${BASH_REMATCH[0]}
    echo ${BASH_REMATCH[1]}
    echo ${BASH_REMATCH[2]}
fi