我在makefile
中有一个准备存储库的配方,它将所有.sh
文件转换为可执行文件。
在Ubuntu 18.04中,以下makefile
SHELL:=/bin/bash
prepare_repo:
pip install flake8==3.6.0
rm -f .git/hooks/pre-commit
flake8 --install-hook git
git config --bool flake8.strict true
sed '/__main__/r'<(\
echo -e " import subprocess\n\
subprocess.check_call(\"find . -name '*.sh' \n\
-exec sh -c ' \n\
for f do \n\
git check-ignore -q '$f'|| \n\
printf '%s\\\n' '$f' \n\
done \n\
' find-sh {} + | xargs git update-index --chmod=+x\", shell=True)"\
) -i -- .git/hooks/pre-commit
我迷上了pre-commit
事件,因为我想将不在.gitignore文件中的所有.sh
文件都转换为可执行文件。
但是问题是,如果我进入.git/hooks/pre-commit
,我将找到以下代码
#!/home/fadi/anaconda3/bin/python
import sys
from flake8.main import git
if __name__ == '__main__':
import subprocess
subprocess.check_call("find . -name '*.sh'
-exec sh -c '
for f do
git check-ignore -q ''||
printf '%s\n' ''
done
' find-sh {} + | xargs git update-index --chmod=+x", shell=True)
sys.exit(
git.hook(
strict=git.config_for('strict'),
lazy=git.config_for('lazy'),
)
)
请注意此代码块$
的转义方式。
git check-ignore -q ''||
printf '%s\n' ''
您用make
中的美元逃脱了美元。
all:
echo $$
prepare_repo:
...
...
git check-ignore -q '$$f'|| \n\
printf '%s\\\n' '$$f' \n\
...
这可能对您有用(GNU sed和shell):
cat <<EOF | sed -i -- '/__main__/r /dev/stdin' .git/hooks/pre-commit
import subprocess\n\
subprocess.check_call(\"find . -name '*.sh'
-exec sh -c '
for f do
git check-ignore -q '$f'||
printf '%s\\\n' '$f'
done
' find-sh {} + | xargs git update-index --chmod=+x\", shell=True)"
EOF
使用猫和管子而不是<(...)
N.B。 "
的报价可能需要调整。