¿Cómo hacer una declaración if not en shell (/bin/sh)?

¿Cómo hacer una declaración if not en shell (/bin/sh)?

Estoy usando Shell para escribir un archivo git hook, para verificar mi mensaje de confirmación antes de la confirmación. Soy un principiante total, esto es lo que he probado:

Mi commit-msgarchivo de enlace es el siguiente:

#!/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

Entonces, cada vez que hago un mensaje de confirmación como este:

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

Así que estoy bastante seguro de que mi mensaje de confirmación tiene más de 20 caracteres y el número de ticket, pero cada vez que lo confirmo, aparece el error que configuré.

Creo que mi problema de lógica es que debería usar if not echo $msg | egrep -qv '(Android-\d{3,4}.{20,})', así que intenté:

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

Pero esto me da este error: .git/hooks/commit-msg: line 5: syntax error near unexpected token !'

Pregunta:

  1. ¿Qué me salió mal y eso provocó que no se pudiera confirmar, a pesar de que envié un mensaje de confirmación correcto?

  2. ¿Cómo puedo arreglarlo?

Respuesta1

Su expresión regular usa sintaxis PCRE como \d, pero grep -E(eso es lo que egrepes, pero grep -Esu uso egrepestá en desuso) no entiende eso. Además, no necesita los paréntesis allí, en realidad no está capturando nada. Si tienes GNU grep, puedes usar grep -Pen su lugar:

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

En caso contrario tendrás que sustituirlo \dpor [0-9]:

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

Sin embargo, no necesita (ni desea) tomar solo la primera línea del archivo, puede simplemente buscar todo el archivo directamente. Tampoco es necesario invertir la coincidencia ( -v), eso sólo complica las cosas. Aquí hay una versión funcional más simple de su script, que se usa if !para negar la condición:

#!/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

Respuesta2

Aquí yo haría:

#! /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'

(elimine ^si no requiere que el número de boleto esté al comienzo de la fila).

información relacionada