如何在 shell (/bin/sh) 中製作 if not 語句?

如何在 shell (/bin/sh) 中製作 if not 語句?

我正在使用 shell 編寫一個 git hook 文件,以在提交之前檢查我的提交訊息。我是一個完全的初學者,這是我嘗試過的:

我的commit-msg鉤子文件如下:

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

所以每當我發出這樣的提交訊息時:

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

所以我很確定我的提交訊息和票號超過 20 個字符,但每次提交時仍然會出現我設定的錯誤。

我認為我的邏輯問題是我應該使用if not echo $msg | egrep -qv '(Android-\d{3,4}.{20,})',所以我嘗試:

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

但這給了我這個錯誤: .git/hooks/commit-msg: line 5: syntax error near unexpected token !'

問題:

  1. 即使我發出了正確的提交訊息,我出了什麼問題導致無法提交?

  2. 我該如何修復它?

答案1

您的正規表示式使用 PCRE 語法,例如\d,但是grep -E(這就是您的語法egrep,但使用grep -Eegrep已被棄用)不明白這一點。另外,您不需要那裡的括號,您實際上並沒有捕獲任何內容。如果你有 GNU grep,你可以使用grep -P

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

如果沒有,您將必須替換\d[0-9]

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

但是,您不需要(或想要)只取得檔案的第一行,您可以直接 grep 整個檔案。您也不需要反轉配對 ( -v),這只會讓事情變得複雜。這是腳本的一個更簡單的工作版本,用於if !否定條件:

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

答案2

在這裡,我會這樣做:

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

^如果您不需要票號位於行首,請刪除 )。

相關內容