Afficher uniquement le nom du répertoire actuel (pas le chemin complet) à l'invite de bash

71

La configuration actuelle de mon invite bash indique le chemin d'accès complet au répertoire actuel. Ceci est agaçant lorsque je suis au fond d’une arborescence de répertoires, car l’invite devient si longue que chaque commande se termine à la ligne suivante. Comment puis-je lui faire montrer que la dernière partie du chemin?

Voici ce que j'ai dans mon .bashrc:

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

# 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/$HOME/~}\007"'
    ;;
*)
    ;;
esac
hsribei
la source

Réponses:

98

Changez le \w(minuscule) en \W(majuscule):

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '
                                                                                       ^^
           this one waaaaaay over here ------------------------------------------------+    

Consultez le HOWTO Bash Prompt pour de nombreux détails amusants. exemple:

user@host:/usr/local/bin$ echo $PS1
${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\$ 

user@host:/usr/local/bin$ export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\W\[\033[00m\]\$ '

user@host:bin$

La PROMPT_COMMANDvariable, si définie, est une commande à exécuter avant d'afficher l'invite spécifiée dans PS1. Dans votre cas, PROMPT_COMMANDexécute une echoinstruction avec certaines séquences d'échappement ANSI qui manipulent la barre de titre d'un Xterm .

Si vous pensez que PROMPT_COMMANDvotre PS1message annule votre invite, vous pouvez le unsetfaire et tester des choses:

$ unset PROMPT_COMMAND

Enfin, assurez-vous de changer la PS1définition qui est réellement utilisée. Lieux communs sont /etc/bash.bashrc, /etc/profile, ~/.bashrc, ~/.bash_profile, ~/.profile. Les fichiers système sont généralement (mais pas toujours) exécutés avant les fichiers utilisateur.

Quack Quack
la source
Hm ... j'ai bien peur que ce soit déjà fait, mais il semble que cette casedéclaration la remplace lorsque je suis sur un xterm, et le problème semble être lié PWDà la PROMPT_COMMANDligne. Savez-vous ce que je devrais y mettre?
Hsribei
4
\w(minuscule) le définit sur chemin complet, \W(majuscule) coupe le bit final. PROMPT_COMMAND définit le titre de la fenêtre dans un xterm. vérifiez votre variable TERM; si elle ne commence pas par "xterm" ou "rxvt", alors PROMPT_COMMAND ne sera même pas exécuté.
Quack Quichotte
Oh, oui, duh. Désolé, j'ai mélangé les majuscules et les minuscules. Ça a marché. Merci! :)
hsribei
Très bonne réponse. Assurez-vous de redémarrer pour que cela prenne effet. Merci!
Combinez
14

La commande de remplacement bash simple est

${VAR/pattern_to_find/pattern_to_replace}

Pour afficher le dernier répertoire, vous pouvez simplement le faire ${PWD/*\//}, c'est-à-dire trouver tout ce qui précède le dernier et y compris le dernier ' /' et le remplacer par rien.

Sur ma machine Ubuntu, j'utilise:

export PS1='$(whoami):${PWD/*\//}#'. 
stopBugs
la source
1
J'aime mieux cette réponse que celle acceptée car elle est générique dans n'importe quelle situation au lieu de se limiter à la logique d'analyse syntaxique spéciale de $ PS1. Moins d'outils plus puissants sont plus faciles à mémoriser et à composer. :)
David Ellis
4

Ma solution consiste à afficher les trois répertoires supérieurs et inférieurs 2 lorsqu'il y a plus de 5 répertoires.

Donc, mon invite (qui a aussi d'autres informations) ressemble à ceci:

08:38:42 durrantm U2017 /home/durrantm/Dropbox/_/rails/everquote

quand mon pwd est réellement

/home/durrantm/Dropbox/93_2016/work/code/ruby__rails/rails/everquote

Mon invite PS1 est configurée comme suit:

HOST='\[\033[02;36m\]\h'; HOST=' '$HOST
TIME='\[\033[01;31m\]\t \[\033[01;32m\]'
LOCATION=' \[\033[01;34m\]`pwd | sed "s#\(/[^/]\{1,\}/[^/]\{1,\}/[^/]\{1,\}/\).*\(/[^/]\{1,\}/[^/]\{1,\}\)/\{0,1\}#\1_\2#g"`'
BRANCH=' \[\033[00;33m\]$(git_branch)\[\033[00m\]\n\$ '
PS1=$TIME$USER$HOST$LOCATION$BRANCH

git_branch est une fonction qui montre la branche courante de git, je la garde dans mes fichiers dot, c’est:

git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
  }
Michael Durrant
la source
C'est génial! Merci beaucoup pour cette réponse.
Carlos F
4

Ma solution à cela est légèrement différente en ce qui concerne la façon de l'exporter. Je pensais donc la partager ici:

Créez une autre variable de chaîne d'invite; PS5 et exportez la chaîne suivante dans votre fichier .profile/ .bash_profile:

\ u : Affiche le nom d'utilisateur actuel.

\ W : Affiche la base du répertoire de travail actuel.

# Display username and current directory only.
export PS5='export PS1="\u:\W$";';

Maintenant, chaque fois que vous devez utiliser le PS raccourci, exécutez simplement: eval $PS5


Ou mieux encore, créez un alias dans votre .bash_aliasesfichier: (grâce à @muru )

alias PS5='export PS1="\u:\W$";';

sourceencore une fois, et maintenant vous pouvez simplement taper PS5pour basculer.

U -ways
la source
1
Cela ressemble à un frankenalias. Pourquoi ne pas simplement utiliser un alias ou une fonction?
Muru
1

Afficher uniquement le nom du répertoire actuel (pas le chemin complet) à l'invite de bash

La plupart des autres solutions ne fonctionnaient pas pour moi sur tous les systèmes d'exploitation partageant mes fichiers de points: AIX, Windoze et Linux. Les ports bash étaient d'anciennes versions qui ne prenaient pas en charge certaines constructions et je ne voulais pas créer un autre processus (c'est sed-à- dire awk, etc.) qui est sensiblement coûteux sous cygwin.

Ce qui suit est long mais performant:

# takes a number argument of the number of last dirs to show
function DIR_LAST {
    # read -a didn't seem to work under bash 3
    IFS='/' array=($PWD)
    len=${#array[@]}
    start=$((len - $1))
    # leading / if fewer dir args: /usr/flastname not usr/flastname
    if (( $start <= 1 )); then
        start=1
        echo -n /
    fi
    for (( i = $start; $i < $len; i++ )); do
        if (( $i > $start )); then
            echo -n /
        fi
        echo -n ${array[$i]}
    done
}
export PS1="\$(DIR_LAST 2) {$(hostname)} "

Je veux que ça crache:

/
/usr
/usr/foo
foo/bin

Remarquez l'absence de barre oblique dans la dernière ligne, ce qui me plait. En outre, vous pouvez cracher les 3 derniers répertoires en changeant l'argument en DIR_LAST.

De plus, j'ai essayé de faire cela avec une regex et BASH_REMATCHbash v3 ne semblait pas aimer les parens et je ne pouvais pas trouver comment leur échapper correctement. Soupir.

gris
la source
0

Je crois que cette option est beaucoup plus facile, simplement en faisant:

echo $PWD | rev | cut -d '/' -f 1 | rev

Donc, assignez ceci à la variable PS1 dans votre fichier .bashrc:

PS1='$(PWD | rev | cut -d '/' -f 1 | rev)'
Dani Mach
la source
0
root:~/project#  -> root:~/project(dev)# 

ajoutez le code suivant à la fin de votre ~ / .bashrc

force_color_prompt=yes
color_prompt=yes
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(parse_git_branch)\$ '
fi
unset color_prompt force_color_prompt
Ali Alp
la source