Bash – 通过运行第二个命令更新terminal标题

在Ubuntu的terminal上,我经常运行长时间运行的程序。 而且由于有很多这些程序,我会一直忘记哪个terminal是哪个程序,除非我通过所有这些标签。 所以我想find一种方法来更新我的terminal标题到程序名称,每当我运行一个命令。 我不想手动做。

我使用GNOMEterminal,但答案不应该真的依赖于此。 基本上,如果我能够运行第二个命令,那么我可以简单地使用gconftool命令来更新标题。 所以我希望find一种方法来捕捉命令在bash中,并在每个命令后更新标题。 我怎么做?

我对你有一些答案:)你说的没错,你使用的是gnome-terminal,但是你使用的是什么命令shell并不重要。 这在zsh是很容易的,但在接下来我将假定你使用的是bash ,而且这是一个相当新的版本(> 3.1)。

首先:

哪个环境变量会包含当前的“命令”?

有一个环境变量或多或少有你想要的 – $BASH_COMMAND 。 只有一个小问题,那就是它只会显示管道中的最后一个命令。 我不是100%确定它会做什么与subshel​​l的组合,要么:)

所以我希望找到一种方法来捕捉命令在bash中,并在每个命令后更新标题。

我一直在想这个,现在我明白你想做什么,我意识到真正的问题是你需要每个命令更新标题。 这意味着$PROMPT_COMMAND$PS1环境变量是可能的解决方案,因为它们只命令返回执行。

bash ,我能想到的唯一方法就是(ab)使用DEBUG SIGNAL。 所以这里有一个解决方案 – 坚持在你的.bashrc的末尾:

 trap 'printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}"' DEBUG 

为了解决这个问题,我一直在搞这个:

 function settitle () { export PREV_COMMAND=${PREV_COMMAND}${@} printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}" export PREV_COMMAND=${PREV_COMMAND}' | ' } export PROMPT_COMMAND=${PROMPT_COMMAND}';export PREV_COMMAND=""' trap 'settitle "$BASH_COMMAND"' DEBUG 

但我不承诺这是完美的!

尝试这个:

 trap 'echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' DEBUG 

感谢history 1 ,即使对于复杂的表达式也能正常工作:

 true && (false); echo $? | cat 

依靠$ BASH_COMMAND或$ @的方法失败。 例如西蒙的显示器:

 true | echo $? | cat 

感谢吉尔斯和西蒙提供的灵感。

我看到了斯托尼想做什么,除了比需要更多的工作。 而且不会因重新定义'cd'而导致各种其他可能不好的事情发生,而只是为了改变目录而放入所有的测试。 Bash已经建立了对这个大部分的支持。

你可以把它放在你的.bashrc的任何地方,在你设置你当前的PS1提示符后(这种方式只是把它提前)

 # If this is an xterm set the titlebar to user@host:dir case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;\u@\h: \w\a\]$PS1" ;; *) ;; esac 

我正在做这样的事情,在标题中显示我的pwd ,可以修改它来做任何你想要的标题:

 function title { echo -en "\033]2;$1\007"; } function cd { dir=$1; if [ -z "$dir" ]; then dir=~; fi; builtin cd "$dir" && title `pwd`; } 

我只是扔在我的~/.bash_aliases

更新

我用我最初的答案遇到了奇怪的错误。 我最终挑选了默认的Ubuntu PS1,并将其分解成多个部分,以实现其中一个部分是标题:

 # simple prompt COLOR_YELLOW_BOLD="\[\033[1;33m\]" COLOR_DEFAULT="\[\033[0m\]" TITLE="\[\e]0;\u@\h:\w\a\]" PROMPT="\w\n$ " HUH="${debian_chroot:+($debian_chroot)}" PS1="${COLOR_YELLOW_BOLD}${TITLE}${HUH}${PROMPT}${COLOR_DEFAULT}" 

没有闯入变量,它会看起来像这样:

 PS1="\[\033[1;33m\]\[\e]0;\u@\h:\w\a\]${debian_chroot:+($debian_chroot)}\w\n$ \[\033[0m\]" 

OP要求bash ,但其他人可能有兴趣了解( 如上所述 ),使用zsh shell确实容易zsh 。 例:

 # Set window title to command just before running it. preexec() { printf "\x1b]0;%s\x07" "$1"; } # Set window title to current working directory after returning from a command. precmd() { printf "\x1b]0;%s\x07" "$PWD" } 

preexec$1包含键入命令(需要启用shell历史,这似乎是一个公平的假设), $2扩展命令(shell别名等)和$3 “非常扩展”命令(shell函数体)。 (更多)

您可以设置bash ,以便每次启动外部程序时都会向终端发送特定的转义序列。 如果使用终端用来更新标题的转义序列,则应解决问题。

我以前用过,所以我知道这是可能的。 但是我不记得那是我的头顶,现在没有时间研究细节。

基于自动定位putty窗口的需要,我在Debian / Ubuntu系统上修改了我的/etc/bash.bashrc文件。 我已经发布了完整的内容,但相关位开始在# Display command ...注释行。

 # System-wide .bashrc file for interactive bash(1) shells. # To enable the settings / commands in this file for login shells as well, # this file has to be sourced in /etc/profile. # If not running interactively, don't do anything [ -z "$PS1" ] && return # check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize # set variable identifying the chroot you work in (used in the prompt below) if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then debian_chroot=$(cat /etc/debian_chroot) fi # set a fancy prompt (non-color, overwrite the one in /etc/profile) PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' # Display command run in title which allows us to distinguish Kitty/Putty # windows and re-position easily using AutoSizer window utility. Based on a # post here: http://mg.pov.lt/blog/bash-prompt.html case "$TERM" in xterm*|rxvt*) # Show the currently running command in the terminal title: # http://www.davidpashley.com/articles/xterm-titles-with-bash.html show_command_in_title_bar() { case "$BASH_COMMAND" in *\033]0*) # The command is trying to set the title bar as well; # this is most likely the execution of $PROMPT_COMMAND. # In any case nested escapes confuse the terminal, so don't # output them. ;; *) echo -ne "\033]0;${USER}@${HOSTNAME}: ${BASH_COMMAND}\007" ;; esac } trap show_command_in_title_bar DEBUG ;; *) ;; esac # Commented out, don't overwrite xterm -T "title" -n "icontitle" by default. # If this is an xterm set the title to user@host:dir #case "$TERM" in #xterm*|rxvt*) # PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"' # ;; #*) # ;; #esac # enable bash completion in interactive shells if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi # if the command-not-found package is installed, use it if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then function command_not_found_handle { # check because cnf could've been removed in the meantime if [ -x /usr/lib/command-not-found ]; then /usr/bin/python /usr/lib/command-not-found -- "$1" return $? elif [ -x /usr/share/command-not-found/command-not-found ]; then /usr/bin/python /usr/share/command-not-found/command-not-found -- "$1" return $? else printf "%s: command not found\n" "$1" >&2 return 127 fi } fi 

我已经测试了三种方法,一切都可以,为了您的快乐使用任何一种方法。

 export PROMPT_COMMAND='echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' trap 'echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' DEBUG trap 'echo -ne "\e]0;"; echo -n $BASH_COMMAND; echo -ne "\a"' DEBUG 

请注意,如果使用$ BASH_COMMAND,则不能识别bash别名,并使用PROMPT_COMMAND show finished命令,但使用trap show running命令。