由于自动提交和推送的脚本存在一些问题,我想实施白名单。
计划是,只允许在路径中使用模式'foo'和'bar'提交。
#!/bin/sh
WHITELIST="foo bar"
WRKDIR=/home/athur/workwork/test/repo
cd $WRKDIR
git add -A
for file in `git diff --cached -p --name-status | cut -c3-`; do
if [[ "$file" == *"$WHITELIST"* ]] ; then
echo "$file is on whitelist"
else
echo "$file is not on whitelist. Commit aborted."
exit 1
fi
done
问题是,它总是使用'else'子句。 我找不到问题。谢谢
答案 0 :(得分:1)
作为最佳实践方法,请考虑:
#!/usr/bin/env bash
# ^^^^ important: [[ ]] is not guaranteed to work with bin/sh
whitelist_re='(foo|bar)'
workdir=/home/athur/workwork/test/repo
cd -- "$workdir" || exit
git add -A
while IFS= read -r filename; do
if [[ $file =~ $whitelist ]]; then
echo "$file is on whitelist" >&2
else
echo "$file is not on whitelist; commit aborted." >&2
exit 1
fi
done < <(git diff --cached --name-only)
要逐步完成更改:
bash
指定为外壳,这保证了[[ ]]
和<(...)
之类的扩展名将可用-这是/bin/sh
所没有的保证。while read
循环,而不是尝试使用for
遍历面向行的数据;请参阅DontReadLinesWithFor,以了解此更改背后的原因。=~
可用于测试值是否匹配。git diff --cached --name-status
然后使用cut
来事后删除状态数据,而是使用--name-only
首先仅生成名称。export
,这些约定也适用。)顺便说一句,如果您只是想找出是否存在任何不匹配项,而又不知道它们是哪些文件,则可以使用:
#!/bin/sh
# ^^ actually safe here, as no non-POSIX functionality is used
whitelist_re='foo|bar'
if git diff --cached --name-only | grep -qEv "$whitelist_re"; then
echo "At least one file is not on whitelist; commit aborted" >&2
exit 1
fi
答案 1 :(得分:0)
使用明确列表
在这种情况下,==
不是对称的,**
似乎使用不当。
尝试"$WHITELIST" == *"$file"*
。
(受How do I check if a variable exists in a list in BASH启发)
请注意,使用您的WHITELIST
,只会将文件foo
和bar
列入白名单。
检测图案
如果需要检测单个模式,则可能需要构造一个函数,例如:
for entry in $WHITELIST ; do
if [[ "$file" =~ $entry ]] ; then
return 0
fi
done
return 1