git - 作为别名的多行函数不起作用
git - multiline function as alias is not working
我写了一个美化git日志输出的函数(解决中提到的问题)。
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
}
到目前为止一切顺利。
然后,我在 bash 终端中使用以下代码将此函数移植为 git 别名:
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'
现在每次我尝试使用 git l
时,它都会显示 f: 2: Syntax error: "(" unexpected (expecting "}")
。
这可能是什么问题?
您正在编写的脚本包含多个 bash主义。 Git 调用 /bin/sh
,这在您的系统上不是 bash。在 Debian 和 Ubuntu 上,它是破折号,速度更快但功能较少。
Debian specifies the features you may expect in /bin/sh
,基本上就是 POSIX 中的那些,加上 test -a
和 test -o
, local
, echo -n
,以及 kill
和 trap
的一些扩展。这些通常是您可以在 /bin/sh
典型开源操作系统上使用的安全功能子集。
您使用的第一个 non-portable 构造是 shell 数组。这些仅存在于 bash 和 zsh 中,不可移植。另外,使用three-part for循环也是一种bash主义。 POSIX sh 只有 for name in list
语法。 function
的用法类似non-portable.
进程替换(<()
)的使用也是不可移植的。您需要使用 git log
命令作为管道的开头,但由于通常管道的各个部分都是用子 shell 编写的,因此您需要明确说明管道的范围subshell 如果你想正确捕获变量.
我写函数的方式是这样的:
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)
}
我写了一个美化git日志输出的函数(解决
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
}
到目前为止一切顺利。
然后,我在 bash 终端中使用以下代码将此函数移植为 git 别名:
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'
现在每次我尝试使用 git l
时,它都会显示 f: 2: Syntax error: "(" unexpected (expecting "}")
。
这可能是什么问题?
您正在编写的脚本包含多个 bash主义。 Git 调用 /bin/sh
,这在您的系统上不是 bash。在 Debian 和 Ubuntu 上,它是破折号,速度更快但功能较少。
Debian specifies the features you may expect in /bin/sh
,基本上就是 POSIX 中的那些,加上 test -a
和 test -o
, local
, echo -n
,以及 kill
和 trap
的一些扩展。这些通常是您可以在 /bin/sh
典型开源操作系统上使用的安全功能子集。
您使用的第一个 non-portable 构造是 shell 数组。这些仅存在于 bash 和 zsh 中,不可移植。另外,使用three-part for循环也是一种bash主义。 POSIX sh 只有 for name in list
语法。 function
的用法类似non-portable.
进程替换(<()
)的使用也是不可移植的。您需要使用 git log
命令作为管道的开头,但由于通常管道的各个部分都是用子 shell 编写的,因此您需要明确说明管道的范围subshell 如果你想正确捕获变量.
我写函数的方式是这样的:
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)
}