Setzen Sie den Titel des Terminalfensters auf das aktuelle Verzeichnis

71

Wie kann ich die Terminal.app in OS X dazu bringen, das aktuelle Verzeichnis in seinem Fenster- oder Tabulatortitel anzuzeigen?

Ich benutze die Bash-Shell.

Kareman
quelle
Ich frage mich immer, warum nicht einmal Leute, die die Frage beantworten, daran denken, sie abzustimmen.
Cregox

Antworten:

60

Kommt auf deine Muschel an.

Dieser Artikel enthält mehrere Methoden.

Ich persönlich verwende zsh mit einer praktischen precmd () - Funktion, die vor jeder Eingabeaufforderung ausgeführt wird.

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

Obwohl in den anderen Fragen Bash-Methoden aufgeführt sind, haben sie den Alias ​​cd. Bash bietet eine inhärente Methode, die nur die Eingabeaufforderung verkettet.

Bash

bash liefert eine Variable PROMPT_COMMAND, die einen Befehl enthält, der vor der Eingabeaufforderung ausgeführt werden soll. Dieses Beispiel (eingefügt in ~ / .bashrc) setzt den Titel auf "Benutzername @ Hostname: Verzeichnis":

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

Dabei ist \ 033 der Zeichencode für ESC und \ 007 für BEL. Beachten Sie, dass die Anführungszeichen hier wichtig sind: Variablen werden in "..." und nicht in "..." erweitert. PROMPT_COMMAND wird also auf einen nicht erweiterten Wert gesetzt, aber die Variablen in "..." werden erweitert, wenn PROMPT_COMMAND verwendet wird.

PWD erstellt jedoch den vollständigen Verzeichnispfad. Wenn wir die Kurzform '~' verwenden möchten, müssen wir die Escape-Zeichenfolge in die Eingabeaufforderung einbetten, sodass wir die folgenden von der Shell bereitgestellten Eingabeaufforderungserweiterungen nutzen können:

\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

Das Folgende erzeugt also eine Eingabeaufforderung von "bash $" und einen xterm-Titel von "username @ hostname: directory" ...

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

Beachten Sie die Verwendung von [...], die bash anweist, die nicht druckbaren Steuerzeichen bei der Berechnung der Breite der Eingabeaufforderung zu ignorieren. Andernfalls werden Zeilenbearbeitungsbefehle beim Platzieren des Cursors verwirrt.

Darren Hall
quelle
Hätte erwähnen sollen, dass ich bash verwende, ich habe die Frage aktualisiert.
Kareman
Die Bash-Methode wurde über den aufgelisteten Link hinzugefügt.
Darren Hall
1
Sehr gut. Um nur den Pfad zum aktuellen Verzeichnis im Titel und den Namen des aktuellen Verzeichnisses in der Eingabeaufforderung zu erhalten, habe ich gerade PS1 = "\ [\ 033] 0; \ w \ 007 \] \ W \ $" verwendet.
Kareman
1
"Wenn wir die Kurzform '~' verwenden möchten, müssen wir den Escape-String in die Eingabeaufforderung einbetten." Sie können Folgendes verwenden, um den vollständigen Pfadnamen des Ausgangsverzeichnisses durch tilde zu ersetzen: $ {PWD / # $ {HOME} / \ ~}
Chris Seite
1
@MattTagg Sicher, Sie müssen es nur in Ihre ~/.profile(oder eine gleichwertige) Datei auf dem Remote-Computer kopieren .
Coredumperror
32

Kopieren & Einfügen in Datei ~ / .profile:
PROMPT_COMMAND="echo -ne \"\033]0;${PWD##*/}\007\"; $PROMPT_COMMAND"

Dadurch wird der Titel der aktuellen Terminalregisterkarte auf den Namen des Ordners gesetzt, in dem Sie sich befinden (NICHT auf den gesamten Pfad).
Also ...
Developer/Applications/Utilities/Bluetooth/wird =>Bluetooth

Alles ist eins
quelle
3
Bei Außenseitern lautet die zu bearbeitende Datei ~ / .bash_profile
Tom
11

Ab Mac OS X Lion 10.7 verfügt das Terminal über eine explizite Escape-Sequenz zum Festlegen des Arbeitsverzeichnisses, das das Terminal mithilfe des Proxy-Symbols im Standardfenster anzeigt. Auf diese Weise können Sie mit gedrückter Befehlstaste auf den Pfad klicken, ihn im Finder anzeigen oder wie jeden anderen Ordner ziehen. Darüber hinaus kann Terminal damit ein anderes Terminal im selben Verzeichnis erstellen und das Arbeitsverzeichnis wiederherstellen, wenn Terminal beendet / neu gestartet wird (wenn Fortsetzen aktiviert ist). Sie können damit auch Verzeichnisse für Fenstergruppen wiederherstellen.

Es ist dieselbe OSC-Escape-Sequenz (Operating System Command) wie für die Fenster- und Tabulatortitel, jedoch mit dem ersten auf 7 gesetzten Parameter. Der Wert sollte eine "file:" -URL sein, die die Prozentcodierung von Sonderzeichen ermöglicht, damit sie verarbeitet werden können alle gültigen Pfadnamen. Sie sollten auch den Hostnamen angeben, damit Terminal feststellen kann, ob es sich um ein lokales Verzeichnis handelt. Das Terminal verwendet es nicht als aktuelles Arbeitsverzeichnis, wenn es von einem anderen Host stammt.

In ähnlicher Weise unterstützt Terminal das Festlegen der "dargestellten Datei" mithilfe der OSC-Escape-Sequenz mit einem Parameter von 6. Wenn dies festgelegt ist, zeigt das Proxy-Symbol dies anstelle des Arbeitsverzeichnisses an. Zum Beispiel habe ich Emacs und weniger konfiguriert, um die aktuell angezeigte Datei / Puffer im Proxy-Symbol wiederzugeben. Auf diese Weise können diese tty-basierten Programme besser in das umgebende Betriebssystem integriert werden.

Das Verhalten des Arbeitsverzeichnisses ist standardmäßig für Bash (die Standard-Shell unter Mac OS X) aktiviert. Siehe / etc / bashrc für den entsprechenden Code.

Es ist wahrscheinlich auch erwähnenswert, dass Lion Terminal jetzt das Festlegen des Tabulatortitels unabhängig vom Fenstertitel mithilfe der OSC-Escape-Sequenz unterstützt.

Chris Page
quelle
Die update_terminal_cwdFunktion setzt das Proxy-Symbol auf das aktuelle Arbeitsverzeichnis. Standardmäßig $PROMPT_COMMANDist update_terminal_cwd.
Jtbandes
@jtbandes Darauf bezog ich mich, als ich schrieb: "Das Verhalten des Arbeitsverzeichnisses ist für bash standardmäßig aktiviert ...".
Chris Seite
Ja. Ich habe gerade herausgefunden, wie es funktioniert und dachte, es könnte für zukünftige Googler nützlich sein!
Jtbandes
3

Abgesehen von der Empfehlung, dass Sie die Escape-Sequenz für Apple Terminal-spezifische Betriebssystembefehle verwenden: ESC ] Ps ; Pt BELWo Psist 7und Ptist eine file:URL? In Mac OS X 10.11 (und wahrscheinlich seit 10.7) gibt es eine Datei /etc/bashrc_Apple_Terminal(die unter 10.11 nicht mehr bearbeitet werden kann), in der der Komfort definiert ist update_terminal_cwd()als (ohne die Kommentare):

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"
}

Sie können dies auch auf Ihren Remote-Boxen verwenden, falls Sie dies beabsichtigen, und sich dann den Kopf zerkratzen, wenn Sie die Datei-URL in Bash korrekt codieren.

Und wenn Sie ändern PROMPT_COMMANDin Ihrem eigenen .bash_profileoder .bashrcSie vielleicht vergessen , dies zu nennen. In derselben Datei zeigen sie ein Beispiel für eine bessere Verkettung mit:

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

.bash_profileIch persönlich wollte die Git-Eingabeaufforderung hinzufügen, also habe ich Folgendes getan:

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
dlamblin
quelle
1

Bash-Lösungen mit PS1 und PROMPT_COMMAND schlagen beide fehl, wenn das Verzeichnis Unicode-Zeichen enthält (zumindest auf Snow Leopard). Die beste Lösung, die ich finden konnte, war das Äquivalent von

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

Leider funktioniert das nicht direkt, also habe ich stattdessen eine Shell-Funktion definiert, um den trAufruf durchzuführen:

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

Dies funktioniert gut für lateinische Akzente, die in Unicode NFD verwendet werden (die Akzente verschwinden, das zugrunde liegende lateinische Zeichen bleibt jedoch erhalten).

Leider wird es für Dinge wie Chinesisch völlig scheitern.

Michael Norrish
quelle
Ab Mac OS X Lion 10.7 verfügt Terminal über eine explizite Escape-Sequenz zum Festlegen des Arbeitsverzeichnisses. Es wird eine URL verwendet, sodass Sie die Prozentcodierung für Sonderzeichen verwenden und alle gültigen Pfadnamen unterstützen können. Siehe meine Antwort auf diese Frage für Details.
Chris Seite
1

Angenommen, Sie verwenden das Standard-MAC-Terminal, können Sie das folgende in .profile verwenden, da "set_prompt" Sie beim Öffnen einer neuen Registerkarte möglicherweise selbst in den Stammordner sendet:

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
Kopz Kyoto
quelle
0

Geben Sie dies in Ihr ~ / .profile oder eine gleichwertige Datei ein:

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

export PS1='\W \$ '

settitle `pwd`

Die erste Zeile enthält zwei Sonderzeichen, die nicht kopiert / eingefügt werden können. Sie können den Text jedoch hier herunterladen: http://blog.nottoobadsoftware.com/files/setterminaltitle.sh .

Kareman
quelle
1
„Die erste Zeile enthält zwei Sonderzeichen , die nicht kopiert werden können / Einfügen“ Anstelle der Verwendung von echoVerwendung printf, die können Sie diese Zeichen (ESC und BEL / Steuerungs-G) mit Escape - Sequenzen exprimieren:printf '\e]0;$@\a"
Chris Page