【问题标题】:Git bash doesn't recognize 'rev' commandGit bash 无法识别“rev”命令
【发布时间】:2019-09-20 01:55:05
【问题描述】:

我正在尝试使用缩短我的 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

我已经正确设置了PATH,因为除了rev 之外的其他命令都能正常工作。 rev 不是 git bash 的一部分吗?或者有没有其他方法可以只显示 bash 提示符的父目录和当前目录?

操作系统:Windows 10

【问题讨论】:

  • 旁注:你不应该export你的PS1。它应该只为交互式 shell 设置,通常会进入 ~/.bashrc
  • rev 是一个外部命令(一个单独的可执行文件),而不是 shell 本身的一部分;因此,它不是 任何 bash 版本的一部分,而是存在(或不存在)的东西,具体取决于您是否单独安装(或包含在您的操作系统中)。
  • 顺便说一句,在提示符中使用命令替换是一个非常糟糕的主意——它们,在 Windows 上尤其慢。最好只使用本机 shell 逻辑(根本不使用命令替换;bash 有一个 PROMPT_COMMAND 挂钩,您可以使用它来指定一个更改 PS1 的函数,如果操作正确,则根本不涉及分叉子进程)。
  • 使用\wPROMPT_DIRTRIM=2

标签: bash git shell git-bash


【解决方案1】:

您的环境似乎没有rev 命令。但是,您不需要它,有内置工具可以满足您的需求。

要获取PS1 中的当前工作目录,请使用\w

PS1='\w\$ '

这将为您提供完整路径,因此您的提示将类似于

~/tinker/so/subdir/subsubdir$

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

PROMPT_DIRTRIM=2

这会给你一个提示

~/.../subdir/subsubdir$

【讨论】:

  • 我考虑过 DIRTRIM,但只是想要一些更简约的东西,没有点和东西来使提示看起来干净
  • @FatehAK 对于我自己的提示,我做了类似的事情:我只用前三个字符替换除当前目录之外的所有目录名称,因此/path/to/some/nested/directory 将显示为/pat/to/som/nes/directory。我使用PROMPT_COMMAND 创建提示,请参阅here
【解决方案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%/*}/}

通过

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
}

等等……

然后

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.'s answer 上评论$DIRTRIM 后才发布此消息的
  • foo() { echo bar; }; baz=$(foo) 不会在我的 bash 上分叉,它会检测内置并内联运行它。
【解决方案3】:

这是对我有用的代码 -

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

来自link

【讨论】:

  • 考虑在变量中使用函数而不是脚本!见my answer
【解决方案4】:
function last_two_dirs () 
{ 
        awk -F/ '{print ((NF>1)?$(NF-1)"/":"")""$NF}' <<< $PWD
}

【讨论】:

    【解决方案5】:

    你可以简单地使用

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

    改为

    【讨论】:

      【解决方案6】:

      安装MSYS2工具,里面有你需要的工具。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-12
        • 2016-05-24
        • 2016-12-25
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 2015-09-10
        • 1970-01-01
        相关资源
        最近更新 更多