将终端窗口的标题设置为当前目录


71

如何在OS X中获取Terminal.app以在其窗口或选项卡标题中显示当前目录?

我正在使用bash外壳。


我总是想知道,为什么甚至回答这个问题的人也记得记住投票。
cregox '04

Answers:


60

取决于您的外壳。

文章显示多种方法。

我个人使用zsh,它具有方便的precmd()函数,该函数在每个提示之前运行。

    precmd () { print -Pn "\e]2;%n@%M | %~\a" } # title bar prompt

尽管其他问题列出了bash方法,但它们为cd作别名。Bash提供了一种固有的方法,可以将提示链接掉。

重击

bash提供了一个变量PROMPT_COMMAND,其中包含在提示符之前执行的命令。此示例(插入〜/ .bashrc中)将标题设置为“ username @ hostname:directory”:

 PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'

其中\ 033是ESC的字符代码,\ 007是BEL的字符代码。请注意,这里的引号很重要:变量在“ ...”中扩展,而不在“ ...”中扩展。因此,将PROMPT_COMMAND设置为未扩展的值,但是使用PROMPT_COMMAND时,“ ...”内部的变量将被扩展。

但是,PWD会生成完整的目录路径。如果要使用'〜'速记,则需要在提示符中嵌入转义字符串,这使我们可以利用shell提供的以下提示符扩展:

\u          expands to $USERNAME
\h          expands to hostname up to first '.'
\w          expands to directory, replacing $HOME with '~'
\[...\]     embeds a sequence of non-printing characters

因此,以下内容将产生提示“ bash $”和xterm标题“ username @ hostname:directory” ...

 case $TERM in
     xterm*)
        PS1="\[\033]0;\u@\h: \w\007\]bash\$ "
        ;;
     *)
        PS1="bash\$ "
        ;;
 esac

请注意[...]的使用,它告诉bash在计算提示宽度时忽略非打印控制字符。否则,放置光标时,行编辑命令会变得混乱。


应该提到我正在使用bash,我已经更新了问题。
kareman

从列出的链接中添加了bash方法。
达伦·霍尔

1
很好。为了仅获得标题中当前目录的路径和提示符下当前目录的名称,我只使用了PS1 =“ \ [\ 033] 0; \ w \ 007 \] \ W \ $”。
kareman

1
“如果要使用'〜'速记,则需要在提示符中嵌入转义字符串”。可以使用以下命令将完整的主目录路径名替换为波浪号:$ {PWD /#$ {HOME} / \〜}
克里斯·佩奇

1
@MattTagg当然,您只需要将其放入~/.profile远程计算机上的(或等效文件)中即可。
coredumperror

31

复制并粘贴到〜/ .profile文件中:
PROMPT_COMMAND="echo -ne \"\033]0;${PWD##*/}\007\"; $PROMPT_COMMAND"

这会将当前终端选项卡的标题设置为您所在文件夹的名称(不是整个路径)。
所以...
Developer/Applications/Utilities/Bluetooth/变成=>Bluetooth


3
在特立独行者上,要编辑的文件为〜/ .bash_profile
汤姆

11

从Mac OS X Lion 10.7开始,终端机具有用于设置工作目录的显式转义序列,终端机使用标准的窗口“代理”图标显示该转义序列。这使您可以按住Command并单击以查看路径,在Finder中显示或像其他任何文件夹一样将其拖动。此外,终端可以使用它在同一目录中创建另一个终端,并在退出/重新启动终端(启用了恢复)时恢复工作目录。它还可以为窗口组还原目录。

与窗口和选项卡标题的操作系统命令(OSC)转义序列相同,但第一个参数设置为7。该值应为“ file:” URL,该URL允许对特殊字符进行百分比编码,以便可以处理所有有效的路径名。您还应该包括主机名,以便Terminal可以确定它是否是本地目录。如果终端来自其他主机,终端将避免将其用作当前工作目录。

在相关说明中,终端同样支持使用OSC转义序列(参数为6)设置“代表文件”。如果设置,则代理图标将显示该文件而不是工作目录。例如,我配置了emacs并较少配置以在代理图标中反映当前显示的文件/缓冲区。这使这些基于tty的程序可以与周围的OS更加集成。

默认情况下,bash(Mac OS X上的默认外壳程序)启用了工作目录行为。有关相关代码,请参见/ etc / bashrc。

还可能值得一提的是Lion Terminal现在支持使用OSC转义序列独立于窗口标题设置标签标题。


update_terminal_cwd功能会将代理图标设置为当前工作目录。默认$PROMPT_COMMANDupdate_terminal_cwd
jtbandes 2014年

@jtbandes这就是我写“默认情况下为bash启用工作目录行为…”时所指的意思。
克里斯·佩奇

是的 我刚刚发现了它的工作原理,并认为它可能对将来的Google员工有用!
jtbandes 2014年

3

除了推荐您使用苹果终端特定的操作系统命令转义序列:ESC ] Ps ; Pt BEL这里Ps7Pt一个file:URL; 值得补充的是,在Mac OS X 10.11(可能自10.7起)中,有一个文件/etc/bashrc_Apple_Terminal(在10.11下不可编辑)将便利定义update_terminal_cwd()为(无注释):

update_terminal_cwd () 
{ 
    local url_path='';
    { 
        local i ch hexch LC_CTYPE=C LC_ALL=;
        for ((i = 0; i < ${#PWD}; ++i))
        do
            ch="${PWD:i:1}";
            if [[ "$ch" =~ [/._~A-Za-z0-9-] ]]; then
                url_path+="$ch";
            else
                printf -v hexch "%02X" "'$ch";
                url_path+="%${hexch: -2:2}";
            fi;
        done
    };
    printf '\e]7;%s\a' "file://$HOSTNAME$url_path"
}

如果您正在考虑这样做,也可以在远程工具箱上使用它,以防万一,然后在bash中正确编码文件URL。

而且,如果PROMPT_COMMAND您自己进行更改,.bash_profile或者.bashrc您可能会忘记称呼它。在同一文件中,它们显示了一个使用以下方法更好地链接它的示例:

PROMPT_COMMAND="update_terminal_cwd${PROMPT_COMMAND:+; $PROMPT_COMMAND}"

我个人.bash_profile想添加git提示符,所以我这样做了:

local git_path=/Applications/Xcode.app/Contents/Developer/usr/share/git-core
for f in $git_path/git-completion.bash $git_path/git-prompt.sh
do
  if [[ -f "$f" ]]; then
    . "$f"
  fi
done
get_sha() {
    git rev-parse --short HEAD 2>/dev/null
}
if [ "function" = $(type -t __git_ps1) ]; then
    export GIT_PS1_SHOWDIRTYSTATE=1
    GIT_PS1_SHOWSTASHSTATE=1
    GIT_PS1_SHOWUNTRACKEDFILES=1
    GIT_PS1_SHOWCOLORHINTS=1
    GIT_PS1_DESCRIBE_STYLE="branch"
    GIT_PS1_SHOWUPSTREAM="auto git"
    export PROMPT_COMMAND="$PROMPT_COMMAND${PROMPT_COMMAND:+; }"'__git_ps1 "\[\e[0;32m\]\u\[\e[1;32m\]@\h\[\e[0m\]:\[\e[0;34m\]\w\[\e[0m\]" "\$ " "\n{%s $(get_sha)}"'
fi

1

如果目录中包含Unicode字符(至少在Snow Leopard上),则涉及PS1和PROMPT_COMMAND的Bash解决方案都将失败。我能想到的最好的解决方案是做相当于

PS1="\[\033]0;\`pwd | tr -dC '[\000-\177]'\`\007\]\$ "

不幸的是,这不能直接起作用,所以我定义了一个shell函数来进行tr调用:

termtitlefilter () { tr -dC '[\000-\177]'; }
PS1="\[\033]0;\`pwd | termtitlefilter\`\007\]\$ "

这对于将以Unicode NFD表示的拉丁语重音效果很好(该重音将消失,但基本的拉丁字符将保留)。

不幸的是,对于像中国这样的事情,它将完全失败。


从Mac OS X Lion 10.7开始,Terminal具有用于设置工作目录的显式转义序列。它使用URL,因此您可以对特殊字符使用百分比编码,并支持所有有效的路径名。有关详细信息,请参见我对这个问题的回答。
克里斯·佩奇

1

假设您使用的是默认MAC终端,则可以在.profile中使用以下终端,因为在打开新选项卡时,“ set_prompt”本身可能会将您发送到根文件夹:

set_prompt () {
    BASE_PATH="${PWD##*/}"
    echo -ne "\033]0;$BASE_PATH\007"
}
set_my_tab () {
   update_terminal_cwd
   set_prompt
}

PROMPT_COMMAND=set_my_tab

0

将其输入您的〜/ .profile或等效文件中:

function settitle() { echo -n "]0;$@"; }
function cd() { command cd "$@"; settitle `pwd -P`; }

export PS1='\W \$ '

settitle `pwd`

第一行包含两个不能复制/粘贴的特殊字符,但是您可以从此处下载文本:http : //blog.nottoobadsoftware.com/files/setterminaltitle.sh


1
“第一行包含两个不能复制/粘贴的特殊字符”,而不是使用echouse printf,它使您可以使用转义序列来表示这些字符(ESC和BEL / Control-G):printf '\e]0;$@\a"
Chris Page
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.