Por que o operador = ~ fornece um erro de sintaxe no Solaris ao comparar com uma expressão regular

1

Eu usei este trecho de código a seguir

appcount_range="^[1-$APP_COUNT]$"
    until [[ $APP_OPTION =~ $appcount_range ]]
    do
            echo "INVALID CHOICE! Please enter a valid option:"
            read APP_OPTION
    done

Verifica se a opção do menu foi inserida corretamente. E como o APP_COUNT é decidido dinamicamente, não posso codificar as opções válidas. Este trecho de código roda perfeitamente em um servidor baseado em Linux com ksh93, mas o mesmo código fornece um erro de sintaxe em um servidor Solaris com o comando ksh88 dizendo:

syntax error at line ## : '=~' unexpected

Por que o =~ é um opeartor reconhecido em ksh88 e o que devo usar como alternativa para comparar um regex?

    
por Pratik Mayekar 18.06.2018 / 11:47

1 resposta

6

Esse é um erro que o ksh88 (o /bin/ksh do Solaris 10 e mais antigo e /usr/xpg4/bin/sh ) produziria.

Embora a sintaxe [[ ... ]] venha de ksh, =~ inside é um dos poucos bashisms reais. bash na verdade foi o shell que o introduziu (na versão 3.0).

Foi adicionado posteriormente a ksh93 (portanto, funcionaria com /bin/sh e /bin/ksh do Solaris 11 e mais recente) e zsh , com variações (um operador =~ também está disponível no test / [ builin de zsh e yash ). O ksh88 não foi atualizado desde os anos 90 (exceto para correções de bugs, ou correções de conformidade POSIX em alguns sistemas).

Aqui, você não precisa de um regexp, mas um padrão curinga também funcionará:

[[ $APP_OPTION = [1-$APP_COUNT] ]]

Com o operador = (de ksh), o operando à direita é um padrão curinga. Ou você pode usar a maneira padrão de fazer correspondência de padrões:

case $APP_OPTION in
  [1-$APP_COUNT]) ...
esac

Observe que não funcionaria para nenhum valor maior que 9. [1-12] , o mesmo que [21-1] corresponde apenas a 2 e 1 (e possivelmente outros caracteres que combinam o mesmo que 1 em algumas localidades)) .

Os padrões de caracteres curinga do ksh são funcionalmente equivalentes às expressões regulares estendidas (exceto para os operadores {x,y} interval em variantes modernas de EREs), embora com uma sintaxe diferente:

  • . - > %código%
  • ? - > %código%
  • .* - > %código%
  • * - > %código%
  • x* - > %código%
  • *(x) - > %código%
  • x|y - > %código%
  • @(x|y) - > x? (ksh93 tem ?(x) , não em ksh88).

Se você ainda precisasse usar expressões regulares, você precisaria usar um utilitário separado:

expr "x$string" : "x$regexp" # BRE, anchored at the start

STRING=$string RE=$regexp command -p awk '
  BEGIN{exit(!(ENVIRON["STRING"] ~ ENVIRON["RE"]))}'
    
por 18.06.2018 / 12:07