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 -atest -o, local, echo -n,以及 killtrap 的一些扩展。这些通常是您可以在 /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)
}