如何在 shell (/bin/sh) 中进行 if not 语句?

ken*_*ken 3 shell git

我正在使用 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
Run Code Online (Sandbox Code Playgroud)

因此,每当我发出这样的提交消息时:

git commit -m " #Android-123 I pretty sure this is more than 20 character,but it still failed to commit"
Run Code Online (Sandbox Code Playgroud)

所以我很确定我的提交信息超过 20 个字符,还有票号,但每次我提交它仍然得到我设置的错误。

我认为我的逻辑问题是我应该使用if not echo $msg | egrep -qv '(Android-\d{3,4}.{20,})',所以我尝试了:

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

但这给了我这个错误: .git/hooks/commit-msg: line 5: syntax error near unexpected token !'

题:

  1. 即使我发出了正确的提交消息,我也做错了什么导致提交失败?

  2. 我该如何解决?

ter*_*don 6

你的正则表达式使用PCRE语法一样\d,但grep -E(这是你的egrep就是,但是用grep -E相反,egrep已被淘汰)不明白。此外,您不需要那里的括号,您实际上并没有捕获任何内容。如果您有 GNU grep,则可以grep -P改用:

grep -Pqv 'Android-\d{3,4}.{20,}'
Run Code Online (Sandbox Code Playgroud)

如果没有,您将不得不替换\d[0-9]

grep -Eqv 'Android-[0-9]{3,4}.{20,}' 
Run Code Online (Sandbox Code Playgroud)

但是,您不需要(或不想)只取文件的第一行,您可以直接 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
Run Code Online (Sandbox Code Playgroud)