Git bash无法识别'rev'命令

6

我在尝试使用一个可以缩短我的bash提示符的函数。我已将其添加到.bash_profile中:

function last_two_dirs {
   pwd |rev| awk -F / '{print $1,$2}' | rev | sed s_\ _/_
}

export PS1='$(last_two_dirs) $(__git_ps1) ➡  '

但是每次我启动Git Bash时都会出现错误bash: rev: command not found
除了rev命令外,我已经正确设置了PATH,其他命令都能正常工作。 rev不是Git Bash的一部分吗?还是有其他方法只显示父目录和当前目录的Bash提示?
操作系统:Windows 10

1
附注:您不应该“导出”您的“PS1”。它只应该设置为交互式 shell,并且通常会放在“~/.bashrc”中。 - Benjamin W.
rev 是一个外部命令(单独的可执行文件),不是 shell 本身的一部分;因此它不是任何版本的 bash 的一部分,而是存在于(或不存在于)您的操作系统中,取决于它是否已经被单独安装(或与您的操作系统一起包含等)。 - Charles Duffy
顺便提一下,在提示符中使用命令替换是一个非常糟糕的想法——它们很慢,在Windows上尤其慢。更好的方法是只使用本地shell逻辑(完全不使用命令替换;bash有一个PROMPT_COMMAND钩子,您可以使用它来指定一个函数来更改PS1,如果正确执行将不涉及任何分叉子进程)。 - Charles Duffy
使用\wPROMPT_DIRTRIM=2 - chepner
6个回答

5
你的环境似乎没有rev命令。然而,你不需要它,因为有内置工具可以达到你想要的效果。
要在你的PS1中获取当前工作目录,请使用\w
PS1='\w\$ '

这将获取完整的路径,因此您的提示符将类似于

~/tinker/so/subdir/subsubdir$

现在,将 $PROMPT_DIRTRIM 变量设置为要保留的尾部目录数:
PROMPT_DIRTRIM=2

这将为您提供一个类似的提示:
~/.../subdir/subsubdir$

我考虑过使用DIRTRIM,但只想要更简约的东西,没有点和其他东西,以使提示符看起来更干净。 - Fateh AK
@FatehAK 对于我的提示符,我做了类似的事情:我将除当前目录以外的所有目录名称替换为仅前三个字符,因此/path/to/some/nested/directory将显示为/pat/to/som/nes/directory。我使用PROMPT_COMMAND来创建我的提示符,请参见这里 - Benjamin W.
看起来 ... 只是一个微不足道的代价,但它能清晰地表明你正在省略完整的目录并避免在 bash 配置中产生额外的混乱。 - chepner

2

函数环绕 $PWD

中,有很多技巧和功能可以让这个过程更快速、更有效率。

仅显示最后两个路径级别:

last_two_dirs() {
    local left=${PWD%/*};
    echo "${PWD#${left%/*}/}"
}

更复杂的情况:第一和最后一级:
path_parts() {
    local APATH
    IFS=/ read -a APATH <<<"$PWD"
    if ((${#APATH[@]}>3)) ;then
        echo "/${APATH[1]}..${APATH[-1]}"
    else
        echo "$PWD"
    fi
}

另一个特殊情况
假设您的路径如下:
/srv/dist/invoices-2019/data-2019-02-10/seq-123

将路径的所有部分裁剪到第一个破折号:
path_dash_Trim () {
    local APATH;
    IFS=/ read -a APATH <<< "$PWD";
    APATH="${APATH[*]#*-}";
    echo "${APATH// /\/}"
}

将呈现
/srv/dist/2019/2019-02-10/123

分叉性能问题

为了减少性能问题,有一种适当的方法可以消除分叉(var=$(commnand)):在函数中设置变量:

只需替换:

echo ${PWD#${left%/*}/}

by

printf -v $1 %s "${PWD#${left%/*}/}"

或者更好的是:
printf -v ${1:-myResult} '%s' "${PWD#${left%/*}/}"

样例:
last_two_dirs() { local left=${PWD%/*};printf -v $1 "%s" "${PWD#${left%/*}/}" ;}
last_two_dirs result
printf -v $1 %s "$result"

或者

path_parts() {
    local APATH
    IFS=/ read -a APATH <<<"$PWD"
    if ((${#APATH[@]}>3)) ;then
        printf -v $1 %s "/${APATH[1]}..${APATH[-1]}"
    else
        printf -v $1 %s "$PWD"
    fi
}

and so on...

Then

export -f path_parts
PROMPT_COMMAND='path_parts PS1&&PS1+=" \\$ "'

甚至只是专门的功能:
myPrompt() {
    local APATH fmt='%s\[\e];%s\a\] $ '
    IFS=/ read -a APATH <<<"$PWD"
    if ((${#APATH[@]}>4)) ;then
        printf -v PS1 "$fmt" "/${APATH[1]}..${APATH[-2]}/${APATH[-1]}"{,}
    else
        printf -v PS1 "$fmt" "$PWD"{,}
    fi
}
PROMPT_COMMAND=myPrompt

请注意:我是在您对Benjamin W.的回答中评论了$DIRTRIM之后才发布此内容的。 - F. Hauri - Give Up GitHub
foo() { echo bar; }; baz=$(foo) 在我的bash上不会分叉,它会检测到内置并在内联中运行。 - jthill

2

这是对我有效的代码 -

最初的回答:

PROMPT_COMMAND='case $PWD in
        $HOME) HPWD="~";;
        $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        $HOME/*) HPWD="~/${PWD##*/}";;
        /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        *) HPWD="$PWD";;
      esac'
PS1='$HPWD \$'

referred from link


考虑使用函数而不是变量中的脚本!请参见我的答案 - F. Hauri - Give Up GitHub

1
安装MSYS2工具,它包含你所需的工具。

0
function last_two_dirs () 
{ 
        awk -F/ '{print ((NF>1)?$(NF-1)"/":"")""$NF}' <<< $PWD
}

0

你可以简单地使用

pwd | sed -r 's|.*/([^/]+/[^/]+)$|\1|'

而不是


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接