Como fazer uma declaração if not no shell (/bin/sh)?

Como fazer uma declaração if not no shell (/bin/sh)?

Estou usando o shell para escrever um arquivo git hook, para verificar minha mensagem de commit antes do commit. Sou um iniciante total, foi isso que tentei:

Meu commit-msgarquivo de gancho é como abaixo:

#!/bin/sh
msg=`head -n 1 $1`


if echo $msg | egrep -qv '(Android-\d{3,4}.{20,})'; then
  echo "[Message Format] Your message is not formatted correctly. Correct message format\n 
    #Ticket Number - Minimum 20 or more Character \n 
    like #Android-123 Bug fixed for login issue"
  exit 1;
fi

Então, sempre que eu faço uma mensagem de commit como esta:

git commit -m " #Android-123 I pretty sure this is more than 20 character,but it still failed to commit"

Então, tenho certeza de que minha mensagem de commit tem mais de 20 caracteres e o número do ticket, mas toda vez que eu faço commit ainda recebo o erro que defini.

Acho que meu problema de lógica é que deveria usar if not echo $msg | egrep -qv '(Android-\d{3,4}.{20,})', então tentei:

 if ! [[echo $msg | egrep -qv '(Android-\d{3,4}.{20,})']] ; 
 then....

Mas isso me deu este erro: .git/hooks/commit-msg: line 5: syntax error near unexpected token !'

Pergunta:

  1. O que estou errado que causou a falha no commit, mesmo que eu tenha feito uma mensagem de commit correta?

  2. Como posso consertar isso?

Responder1

Sua expressão regular usa sintaxe PCRE como \d, mas grep -E(isso é o que egrepé, mas o uso grep -Eestá egrepsendo obsoleto) não entende isso. Além disso, você não precisa dos parênteses, na verdade não está capturando nada. Se você tiver GNU grep, poderá usar grep -P:

grep -Pqv 'Android-\d{3,4}.{20,}'

Caso contrário, você terá que substituir \dpor [0-9]:

grep -Eqv 'Android-[0-9]{3,4}.{20,}' 

No entanto, você não precisa (ou deseja) pegar apenas a primeira linha do arquivo, basta digitar o arquivo inteiro diretamente. Você também não precisa inverter a correspondência ( -v), isso apenas complica as coisas. Aqui está uma versão mais simples e funcional do seu script, usada if !para negar a condição:

#!/bin/sh
if ! grep -E 'Android-[0-9]{3,4}.{20,}' "$1"; then
  printf "[Message Format] Your message is not formatted correctly. Correct message format: 
    #Ticket Number - Minimum 20 or more Character 
    like #Android-123 Bug fixed for login issue\n"
  exit 1;
fi

Responder2

Aqui, eu faria:

#! /bin/sh -
file="${1?No file specified}"

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}

awk '
  BEGIN {ret = !ok}
  /^#Android-[[:digit:]]{3,4}[^[:digit:]].{19}/ {ret = ok}
  {exit}
  END {exit ret}' < "$file" || die \
    '[Message Format] Your message is not formatted correctly. Correct message format:' \
    '#Ticket Number - Minimum 20 or more Character' \
    'like #Android-123 Bug fixed for login issue'

(remova ^se não precisar que o número do bilhete esteja no início da fila).

informação relacionada