在 FreeBSD 上,每次 cd 成功切换到 sh 中的另一个目录时,如何创建一个函数 运行?

How can I make a function run every time cd successfully changes to another directory within sh on FreeBSD?

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

  1. \w 有效,但不会将 $HOME 扩展到 ~,所以这是我自己破解的东西

  2. 我可以使用 PS1 来更新终端上的提示,但据我所知,无法使用 PS1 变量来更新标题酒吧也是如此。 ESCBEL 无法像使用 bash 或 ksh

  3. 那样设置标题

这是我的 .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 并且 returns 退出状态为 0.

我打算使用类似于这样的别名:

alias cd="cd  && update_prompt"

但那是在我意识到别名不排除参数之前。我该如何着手做这样的事情?

您可以使用函数代替别名:

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

直接放入~/.shrc即可。你必须在这里使用 command 让 sh 知道你指的是实际的 cd 内置命令而不是你刚刚定义的函数。

启动时参考sh(1) manual page for the details on how to make sh(1)来源~/.shrc文件:

Therefore, a user should place commands that are to be executed only at login time in the .profile file, and commands that are executed for every shell inside the ENV file. The user can set the ENV variable to some file by placing the following line in the file .profile in the home directory, substituting for .shrc the filename desired:

ENV=$HOME/.shrc; export ENV

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

如果交换命令,您可以使用别名+参数来完成:

$ alias cd="echo change; cd"
$ pwd
/nas
$ cd /
change
$ pwd
/
$ cd /etc
change
$ pwd
/etc
$