Wie erstelle ich eine „if not“-Anweisung in der Shell (/bin/sh)?

Wie erstelle ich eine „if not“-Anweisung in der Shell (/bin/sh)?

Ich verwende Shell, um eine Git-Hook-Datei zu schreiben und meine Commit-Nachricht vor dem Commit zu überprüfen. Ich bin ein absoluter Anfänger und habe Folgendes versucht:

Meine commit-msgHook-Datei sieht wie folgt aus:

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

Wenn ich also eine Commit-Nachricht wie diese mache:

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

Ich bin mir also ziemlich sicher, dass meine Commit-Nachricht mehr als 20 Zeichen und die Ticketnummer umfasst, aber bei jedem Commit erhalte ich trotzdem den von mir festgelegten Fehler.

Ich glaube, mein Logikproblem besteht darin, dass ich verwenden sollte if not echo $msg | egrep -qv '(Android-\d{3,4}.{20,})', also habe ich Folgendes versucht:

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

Aber das gibt mir diesen Fehler: .git/hooks/commit-msg: line 5: syntax error near unexpected token !'

Frage:

  1. Was habe ich falsch gemacht, sodass das Commit fehlgeschlagen ist, obwohl ich eine richtige Commit-Nachricht gesendet habe?

  2. Wie kann ich es reparieren?

Antwort1

Ihr regulärer Ausdruck verwendet PCRE-Syntax wie \d, aber grep -E(das egrepist Ihr, aber verwenden Sie grep -Estattdessen, egrepwird veraltet) versteht das nicht. Außerdem brauchen Sie die Klammern dort nicht, Sie erfassen eigentlich nichts. Wenn Sie GNU haben grep, können Sie grep -Pstattdessen Folgendes verwenden:

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

Wenn nicht, müssen Sie es \ddurch Folgendes ersetzen [0-9]:

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

Sie müssen (oder wollen) jedoch nicht nur die erste Zeile der Datei verwenden, sondern können die gesamte Datei direkt greppen. Sie müssen auch die Übereinstimmung ( -v) nicht umkehren, das würde die Sache nur verkomplizieren. Hier ist eine einfachere, funktionierende Version Ihres Skripts, die verwendet wird, if !um die Bedingung zu negieren:

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

Antwort2

Hier würde ich Folgendes tun:

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

(Entfernen Sie das ^, wenn die Ticketnummer nicht am Anfang der Zeile stehen muss).

verwandte Informationen