首页 > 解决方案 > 每次 cd 在 FreeBSD 上成功更改到 sh 中的另一个目录时,如何使函数运行?

问题描述

我在 FreeBSD 上使用 sh 作为我的 shell,但我希望能够有一个漂亮的提示,就像在 Ubuntu 上给我的一个 bash 一样。就 PS1 转义字符而言,FreeBSD 的 sh 实现似乎缺少两点:

  1. \w作品但没有扩展$HOME~,所以这是我自己已经破解的东西

  2. 我可以使用 PS1 更新终端上的提示,但据我所知,也不可能使用 PS1 变量来更新标题栏。ESC如果他们使用 bash 或 ksh ,BEL则无法按预期设置标题

这是我的 .shrc 文件

update_prompt() {
    case "$PWD" in
        "$HOME"*)
            pretty_pwd="~${PWD#*"${HOME}"}"
            ;;
        "/usr$HOME"*)
            pretty_pwd="~${PWD#*"/usr${HOME}"}"
            ;;
        *)
            pretty_pwd="$PWD"
            ;;
    esac

    case "$TERM" in
        xterm*|rxvt*)
            PS1="[$USER@\\h $pretty_pwd]\\$ "
            ;;
        *)
            ;;
    esac

    printf "\\033]0;[%s@$(hostname -s): %s]\\007" "$USER" "$pretty_pwd"
}

update_prompt

因此,当我启动终端或通过 ssh 登录时,它会给出我喜欢的漂亮提示。但是现在我需要这个函数在每次执行 cd 并返回退出状态 0 时运行。

我将使用类似于以下内容的别名:

alias cd="cd $1 && update_prompt"

但那是在我意识到别名不除了参数之前。我该怎么做这样的事情?

标签: shfreebsd

解决方案


您可以使用函数而不是别名:

cd() {
  command cd "$@" && update_prompt
}

把它放进去~/.shrc。您必须使用commandhere 让 sh 知道您指的是实际的cd内置命令,而不是您刚刚定义的函数。

有关如何在sh(1)启动时获取文件的详细信息,请参阅sh(1)手册页:~/.shrc

因此,用户应该在文件中放置仅在登录时执行的.profile命令,以及在文件中为每个 shell 执行的命令ENV。用户可以ENV通过将以下行放在主目录中的文件 .profile 中来将变量设置为某个文件,替换 .shrc所需的文件名:

ENV=$HOME/.shrc; export ENV

我在cd别名管理器中使用了这个技巧。这是函数源代码的链接:https ://github.com/0mp/goat/blob/v2.5.0/libgoat.sh#L31-L57


推荐阅读