Linux环境下SVN预提交钩子脚本语法错误排查求助
SVN预提交钩子脚本语法错误排查与修复
问题回顾
你想要创建一个SVN预提交钩子,检查待提交文件的新增行中是否包含builder_group字符串,若包含则终止提交。但编写的脚本执行时出现了语法错误:
svn: E165001: Commit failed (details follow): svn: E165001: Commit blocked by pre-commit hook (exit code 2) with output: /etc/svn/testrepo/hooks/pre-commit: line 7: conditional binary operator expected /etc/svn/testrepo/hooks/pre-commit: line 7: syntax error near "^+cod_bank">' /etc/svn/testrepo/hooks/pre-commit: line 7: `$SVNLOOK diff "$REPOS" -t "$TXN" | [[ grep "^+builder_group">/dev/null exit 0 ]] ||'
错误原因分析
你的脚本存在几个关键语法和逻辑问题:
- 错误使用
[[ ]]条件结构:[[ ]]是bash用于条件测试的语法(比如判断文件存在、字符串比较),不能直接在里面执行grep命令。你应该直接执行grep并根据它的退出码判断结果。 - 重定向符号缺少空格:
^+builder_group">/dev/null中>前后没有空格,导致shell把">/dev/null"当成了grep的搜索参数一部分,引发语法解析错误。 - 逻辑判断颠倒:你用了
||(逻辑或),意思是如果前面的命令失败(没找到字符串)才执行报错,但你的需求是找到字符串就报错终止提交,应该用&&(逻辑与)。 - 命令换行/分隔错误:原脚本把多个命令挤在一行,没有正确分隔,导致
exit 1的位置错误,shell无法正确解析。
修正后的脚本
这里提供两种写法,都能实现你的需求:
写法1:使用if判断(更易读)
#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook # 获取提交的变更,过滤新增行中包含builder_group的内容 $SVNLOOK diff "$REPOS" -t "$TXN" | grep -q "^+builder_group" # 如果grep找到匹配(退出码为0),则报错并阻止提交 if [ $? -eq 0 ]; then echo "Error: Files contain 'builder_group' - commit is blocked." >&2 exit 1 fi # 没有匹配到,允许提交 exit 0
写法2:使用&&链式命令(更简洁)
#!/bin/sh REPOS="$1" TXN="$2" SVNLOOK=/usr/bin/svnlook # 当grep找到匹配时,执行报错并退出 $SVNLOOK diff "$REPOS" -t "$TXN" | grep -q "^+builder_group" && { echo "Error: Detected 'builder_group' in added lines - commit failed." >&2 exit 1 } exit 0
关键修正点说明
- 使用
grep -q参数:让grep静默执行,只返回退出码(找到匹配返回0,没找到返回1),不需要额外的>/dev/null来屏蔽输出。 - 逻辑修正:用
&&替代||,确保找到指定字符串时才触发错误提示和终止提交。 - 语法规范:每个命令单独一行,符号前后保留空格,避免shell解析错误。
- 明确退出码:钩子脚本返回
exit 1会阻止提交,返回exit 0则允许提交。
内容的提问来源于stack exchange,提问作者Lanzadonii
相关产品推荐
相关产品推荐

