Nur aktuelles und übergeordnetes Verzeichnis in der Bash-Eingabeaufforderung anzeigen

16

Ich bin neu im Bashing und möchte, dass meine Aufforderung etwas anzeigt, das in tcsh trivial war, aber nach einer guten Google-Suche kann ich es immer noch nicht.

Ich möchte, dass meine Eingabeaufforderung nur das aktuelle und das übergeordnete Verzeichnis enthält:

/parent/currentdir $

In tcsh wird dies erreicht durch:

set prompt = "%C2 %"

Bisher habe ich jedoch in bash nur festgestellt, dass ich pwd analysieren muss, um die gleiche Ausgabe zu erhalten.

Gibt es nicht einen einfacheren Weg wie:

export PS1="$(some_command) $" 
twalbaum
quelle
2
Theoretisch PS1='\w \$'; PROMPT_DIRTRIM=2sollte man das bash-Äquivalent geben, aber das funktioniert auf meinem System nicht richtig.
Mikel
Bei mir funktioniert das überhaupt nicht: GNU bash, Version 3.2.57 (1) -release (x86_64-apple-darwin14).
Twalbaum
PROMPT_DIRTRIMwurde in Bash 4 eingeführt . Ich habe gerade auf Ubuntu 16.04 unter WSL getestet und es hat super funktioniert!
Mike Branski

Antworten:

18

Die Funktionen für die schnelle Steuerung von Bash sind eher statisch. Wenn Sie mehr Kontrolle wünschen, können Sie Variablen in Ihre Eingabeaufforderung aufnehmen. Stellen Sie sicher, dass Sie die promptvarsOption nicht deaktiviert haben .

PS1='${PWD#"${PWD%/*/*}/"} \$ '

Beachten Sie die einfachen Anführungszeichen: Die Variablenerweiterungen müssen zum Zeitpunkt der Anzeige der Eingabeaufforderung und nicht zum Zeitpunkt der Anzeige der Eingabeaufforderung erfolgen PS1 Definition Variablen.

Wenn Sie mehr Kontrolle darüber haben möchten, was angezeigt wird, können Sie Befehlsersetzungen verwenden. Das obige Snippet verliert beispielsweise die ~Abkürzung für das Ausgangsverzeichnis.

PS1='$(case $PWD in
        $HOME) HPWD="~";;
        $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        $HOME/*) HPWD="~/${PWD##*/}";;
        /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        *) HPWD="$PWD";;
      esac; printf %s "$HPWD") \$ '

Dieser Code ist recht umständlich, so , anstatt sie in den von kleben PS1Variable, können Sie die verwenden können , PROMPT_COMMANDvariabel zu laufen Code einzustellen HPWDund dann verwenden , die in Ihrem prompt.

PROMPT_COMMAND='case $PWD in
        $HOME) HPWD="~";;
        $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        $HOME/*) HPWD="~/${PWD##*/}";;
        /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
        *) HPWD="$PWD";;
      esac'
PS1='$HPWD \$'

Da sich die verkürzte Eingabeaufforderung nur bei einer Verzeichnisänderung geändert hat, müssen Sie sie nicht jedes Mal neu berechnen, wenn eine Eingabeaufforderung angezeigt wird. Bash bietet keinen Hook, der bei einem aktuellen Verzeichniswechsel ausgeführt wird, aber Sie können ihn simulieren, indem Sie ihncd und seine Cousins überschreiben .

cd () { builtin cd "$@" && chpwd; }
pushd () { builtin pushd "$@" && chpwd; }
popd () { builtin popd "$@" && chpwd; }
chpwd () {
  case $PWD in
    $HOME) HPWD="~";;
    $HOME/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
    $HOME/*) HPWD="~/${PWD##*/}";;
    /*/*/*) HPWD="${PWD#"${PWD%/*/*}/"}";;
    *) HPWD="$PWD";;
  esac
}
PS1='$HPWD \$'

Beachten Sie, dass Sie nicht exportieren müssen und sollten PS1, da es sich um eine Shell-Einstellung und nicht um eine Umgebungsvariable handelt. Eine Bash- PS1Einstellung würde von anderen Shells nicht verstanden.

PS Wenn Sie eine schöne interaktive Shell-Erfahrung wünschen, wechseln Sie zu zsh , wobei alle diese Funktionen (Eingabeaufforderungserweiterungen, die %weitgehend tcshs umfassen chpwd, usw.) native Funktionen sind.

PS1='%2~ %# '
Gilles 'SO - hör auf böse zu sein'
quelle
2
Dies hätte die akzeptierte und am meisten bewertete Antwort sein sollen.
LarsH
2

Die Syntax zum Abrufen des übergeordneten und des aktuellen Verzeichnisses ist Munais Antwort entnommen .

Wie Gilles jedoch bemerkt hat, zeigt dieser Code nur das aktuelle Verzeichnis zu diesem Zeitpunkt an .bashrc Ladens geladen wird, ändert sich jedoch nicht, wenn Sie im System zu anderen Ordnern navigieren.

Wenn Sie dies in Ihrer .bashrcDatei haben, wird die Eingabeaufforderung automatisch in Ihr aktuelles Verzeichnis aktualisiert:

prompt_command () {
    PS1='$(basename $(dirname "$PWD"))/$(basename "$PWD") $ '
}
PROMPT_COMMAND=prompt_command
twalbaum
quelle
1
Soll die Definition prompt_command()etwas für sich tun? Für mich nicht. Wollten Sie , wie Gilles , auch prompt_command()in Redefinitionen von cd& co verwenden? Oder meintest du PROMPT_COMMAND='...'?
LarsH
2
Dieser Befehl schlägt auch fehl, wenn er $PWDein Leerzeichen enthält.
LarsH
1
Danke, dass du mich darauf zurückbringst. Zitierte die $ PWDs, um Leerzeichen zuzulassen, und schloss den letzten Befehl ein. Meine aktuelle Eingabeaufforderung ist komplexer als diese, daher ist die Definition von prompt_command erforderlich. Ansonsten arbeitet PS1 = ... an.
Twalbaum
Ideen zum Aufräumen der Ausgabe beim Navigieren zu /? Wie geschrieben, erhalten Sie/// $
Ezrock
0

Eingabeaufforderungszeichenfolge kann einfach bashdurch Bearbeiten der Shell-Variablen geändert werden PS1. Es steht für Prompt String 1. Mehr Infos hier .

Feuern Sie jetzt Ihre bashMuschel an.

vi ~/.bashrc

Hänge die PS1-Definition an die Datei an

`export PS1="$(basename $(dirname $PWD))/$(basename $PWD)"`

Weitere Tutorials hier und hier , damit Sie noch mehr daran arbeiten können.

Munai Das Udasin
quelle
1
Ich verstehe, wie man die Aufforderung ändert. Meine Frage ist, wie man nur das gegenwärtige und übergeordnete Verzeichnis erhält, nicht den vollständigen Pfad.
Twalbaum
@ twalbaum bearbeitete meine Antwort
Munai Das Udasin
froh zu helfen @ Walbaum :)
Munai Das Udasin
1
Dies setzt die Eingabeaufforderung auf das aktuelle Verzeichnis, wenn .bashrces geladen wird. Die Eingabeaufforderung ändert sich nicht, wenn Sie cdin ein anderes Verzeichnis wechseln ! @twalbaum
Gilles '
@ Gilles tut es für mich.
Twalbaum
0

Möglicherweise einfacher mit "~" für das Basisverzeichnis.

function PWDN {
  echo "${PWD/#$HOME/~}" | rev | cut -d "/" -f1 -f2 | rev
}
Baskar
quelle
0
export PS1='[\u@\h $(basename $(dirname ${PWD}))/$(basename ${PWD})]\$ '
export PROMPT_COMMAND='echo -ne "\033]0;$(basename $(dirname $PWD))/$(basename ${PWD})\007"'
Marius
quelle