问题
I have written a function which beautify the git log output (to solve the problem mentioned in different color for data and time in git log output).
function gl() {
my_date=();
my_time=();
while IFS= read -r line; do
my_date+=( $(date +"%d-%m-%Y" -d @$line) )
my_time+=($(date +"%H:%M" -d @$line))
done < <( git log --format="%at" )
for (( n=0; n<${#my_date[@]}; n++ )); do
git --no-pager log -1 --skip=$n --pretty=format:"%C(#d33682)%h %C(#859900)${my_date[$n+1]} %C(#b58900)${my_time[$n+1]} %C(#6c71c4)%ce %C(#2aa198)%s";
printf "\n";
done
}
So far so good.
Then, I port this function as git alias using the following code in my bash terminal:
git config --global alias.l '!f(){
my_date=();
my_time=();
while IFS= read -r line; do
my_date+=( $(date +"%d-%m-%Y" -d @$line) )
my_time+=($(date +"%H:%M" -d @$line))
done < <( git log --format="%at" )
for (( n=0; n<${#my_date[@]}; n++ )); do
git --no-pager log -1 --skip=$n --pretty=format:"%C(#d33682)%h %C(#859900)${my_date[$n+1]} %C(#b58900)${my_time[$n+1]} %C(#6c71c4)%ce %C(#2aa198)%s";
printf "\n";
done
}; f'
Now every time I try to use git l
, It says f: 2: Syntax error: "(" unexpected (expecting "}")
.
What might be the issue here?
回答1:
The script you're writing contains several bashisms. Git invokes /bin/sh
, which on your system is not bash. On Debian and Ubuntu, it's dash instead, which is much faster but less featureful.
Debian specifies the features you may expect in /bin/sh
, which are basically those found in POSIX, plus test -a
and test -o
, local
, echo -n
, and some extensions to kill
and trap
. These are generally a safe subset of features you may use in /bin/sh
on a typical open source operating system.
The first non-portable construct you're using is shell arrays. Those exist only in bash and zsh and are not portable. In addition, the use of the three-part for loop is also a bashism. POSIX sh has only the for name in list
syntax. The use of function
is similarly non-portable.
The use of process substitution (<()
) is also unportable. You'll need to use the git log
command as the beginning of a pipeline, but because typically segments of a pipeline are written in subshells, you'll need to be explicit about the scope of the subshell if you want to capture variables correctly.
The way I would write the function is this:
gl() {
git log --format="%at" | (
n=0;
while IFS= read -r line
do
date=$(date +"%d-%m-%Y" -d @$line)
time=$(date +"%H:%M" -d @$line)
git --no-pager log -1 --skip=$n \
--pretty=format:"%C(#d33682)%h %C(#859900)$date %C(#b58900)$time %C(#6c71c4)%ce %C(#2aa198)%s%n"
n=$((n + 1))
done)
}
来源:https://stackoverflow.com/questions/64408015/git-multiline-function-as-alias-is-not-working