Синтаксическая ошибка = ~ оператор в msysgit bash

Я пытаюсь добавить функцию в my bash_profile на msysgit:

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

но я получаю следующую ошибку:

bash: ожидаемый условный двоичный оператор'

bash: синтаксическая ошибка рядом с =~'

из того, что я могу найти, оператор" equals tilde" (=~) оценивает как регулярное выражение в bash.

почему =~ бросает ошибку?

обновление: вот скриншот ввода его вручную (это работает sh.EXE-файл):

Screenshot of equals tilde (=~) operator failing

4 ответов


обновление 2015: msysgit теперь устарел.
Вы должны использовать bash, который поставляется с git-for-windows.
Как упоминалось в ответ, он использует гораздо более недавний bash (4.3+), для которого =~ синтаксис будет работать.


оригинальный ответ (март 2013 года)

bash, упакованный с msysgit, может быть просто слишком старым, чтобы полностью поддерживать этот оператор.
Это, конечно, слишком старый сравнить с без кавычек выражение, как указано в "bash, начиная с версии 3" и "как использовать регулярные выражения в сценариях bash?":

начиная с версии 3.2 Bash, выражение для соответствия больше не цитируется.

на самом деле mklement0 упоминания в комментариях:

=~ был введен в bash 3.0 и всегда поддерживал маркер без кавычек на RHS.
До 3.1.икс, котируемые токены обрабатывались так же, как и некотируемые токены: оба интерпретировались как regexes.
Что изменилось в 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 /

У меня была такая же ошибка на Bash 3.1.0 от установки Git на Windows. В конце концов я изменил его на:

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

согласно https://groups.google.com/forum#!тема/msysgit / yPh85MPDyfE это потому, что msys не отправляет libregex вместе с bash. Предположительно, если вы компилируете / находите построенный msys libregex и помещаете его в путь библиотеки,=~ начинает работать нормально.


вот решение, которое поддерживает извлечение сопоставленных строк. Если оператор =~ не поддерживается bash, то используется команда 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=
        if [[ ${2: -1} = $ ]]; then
            local regex="(${2%$})()()()()()()()()$"
        else
            local regex="()()()()()()()()().*"
        fi
        regex=${regex//\//\/}
        local replacement="\n\n\n\n\n\n\n\n\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