我正在解析" git log -1 --name-status"的输出。获取上次提交中更改的每个文件的文件扩展名。您可以在http://goo.gl/Ms11a2
上看到一个有效的示例一旦我开始使用tutorialspoint,我试图在git post-commit钩子中运行它,但是readarray line(#9)引发了语法错误。
.git / hooks / post-commit:9:.git / hooks / post-commit:语法错误:重定向意外
你们能指出我正确的方向吗?我做错了什么,为什么它会在http://goo.gl/Ms11a2而不是提交后工作?请原谅我的无知......我对shell脚本没有多少经验。
#!/bin/sh
### git-stats hook (begin) ###
# Copy last commit hash to clipboard on commit
commit_hash=$(git rev-parse HEAD)
repo_url=$(git config --get remote.origin.url)
commit_date=$(git log -1 --format=%cd)
commit_changes=$(git log -1 --name-status)
readarray -t log_lines <<< "$commit_changes"
fileRegex='(.*)\.'
file_changed_start=6;
file_changed_line="${log_lines[file_changed_start]}"
declare -A languages;
# Step through each line that passes the regex
while [[ "${file_changed_line}" =~ ${fileRegex} ]]; do
# Store the file extension
parsePathAndFilename="${BASH_REMATCH[0]}"
fileExtention=${file_changed_line#${parsePathAndFilename}};
# Add 1 to the language that is already defined
let languages[${fileExtention}]++;
file_changed_start=$(($file_changed_start + 1))
file_changed_line="${log_lines[file_changed_start]}"
done
# Create the JSON output
fileTypes="{";
fileTypeTotal=${#languages[@])};
assocKeys=(${!languages[@]});
for changed in "${!languages[@]}"
do
if [[ "$changed" == "${assocKeys[fileTypeTotal-1]}" ]]
then
fileTypes+="\"$changed\" : ${languages[$changed]}";
else
fileTypes+="\"$changed\" : ${languages[$changed]},";
fi
done
# close off the json
fileTypes+="}";
echo $fileTypes
commit_data="\"{ \"date\": \"$commit_date\", \"url\": \"$repo_url\", \"hash\": \"$commit_hash\", \"languages": \"$fileTypes\" }\""
git-stats --record "${commit_data}"
### git-stats hook (end) ###
答案 0 :(得分:1)
“here-string”语法(<<<
)是bash扩展名;它不存在于基本壳中。 (它不是严格意义上的bash;许多其他shell也使用它。)数组和readarray
命令也是如此。
因此,您需要确保使用bash
来运行脚本。您的shebang行(#!/bin/sh
)告诉系统使用基本shell,如果系统上的基本shell不是bash,则可能没有<<<
。
尝试将shebang行更改为
#!/bin/bash
(确保这是bash
的正确路径。您可以使用which bash
进行验证。)