Afficher uniquement le répertoire actuel et parent dans l'invite bash

16

Je suis nouveau sur bash et j'aimerais que mon invite montre quelque chose qui dans tcsh était trivial, mais après une bonne recherche sur google, je ne peux toujours pas le faire.

J'aimerais que mon invite n'inclue que les répertoires actuels et parents comme ceci:

/parent/currentdir $

Dans tcsh, ceci est réalisé par:

set prompt = "%C2 %"

Cependant, en bash jusqu'à présent, j'ai seulement constaté que je dois analyser pwd pour obtenir la même sortie.

N'y a-t-il pas un moyen plus simple, comme faire:

export PS1="$(some_command) $" 
twalbaum
la source
2
En théorie, cela PS1='\w \$'; PROMPT_DIRTRIM=2devrait vous donner l'équivalent bash, mais cela ne fonctionne pas correctement sur mon système.
Mikel
Cela ne fonctionne pas du tout sur le mien: GNU bash, version 3.2.57 (1) -release (x86_64-apple-darwin14).
twalbaum
PROMPT_DIRTRIMa été introduit dans Bash 4 . Je viens de tester sur Ubuntu 16.04 sous WSL et cela a très bien fonctionné!
Mike Branski

Réponses:

18

Les fonctionnalités de contrôle rapide de Bash sont plutôt statiques. Si vous voulez plus de contrôle, vous pouvez inclure des variables dans votre invite; assurez-vous que vous n'avez pas désactivé l' promptvarsoption .

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

Notez les guillemets simples: les extensions de variable doivent se produire au moment où l'invite est affichée, pas au moment où la PS1variable est définie.

Si vous voulez plus de contrôle sur ce qui est affiché, vous pouvez utiliser des substitutions de commande. Par exemple, l'extrait ci-dessus perd l' ~abréviation du répertoire personnel.

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

Ce code est plutôt lourd, donc au lieu de le coller dans la PS1variable, vous pouvez utiliser la PROMPT_COMMANDvariable pour exécuter le code à définir HPWD, puis l'utiliser dans votre invite.

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

Étant donné que l'invite raccourcie n'a été modifiée que lors d'un changement de répertoire, vous n'avez pas besoin de le recalculer chaque fois qu'une invite s'affiche. Bash ne fournit pas de hook qui s'exécute sur un changement de répertoire en cours, mais vous pouvez le simuler en remplaçant cdet ses cousins.

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 \$'

Notez que vous n'avez pas besoin d'exporter et que vous ne devez pas l'exporter PS1, car il s'agit d'un paramètre shell, et non d'une variable d'environnement. Un PS1réglage bash ne serait pas compris par les autres obus.

PS Si vous voulez une belle expérience de shell interactif, passez à zsh , où tous ces éléments ( %extensions rapides englobant largement les tcsh chpwd, etc.) sont des fonctionnalités natives.

PS1='%2~ %# '
Gilles 'SO- arrête d'être méchant'
la source
2
Cela aurait dû être la réponse acceptée et la plus votée.
LarsH
3

La syntaxe d'obtention des répertoires parent et actuel est tirée de la réponse de Munai .

Cependant, comme l'a noté Gilles, ce code affiche uniquement le répertoire actuel au moment du .bashrcchargement, mais il ne changera pas lorsque vous naviguerez sur le système vers d'autres dossiers.

Le fait de l'avoir dans votre .bashrcfichier rend l'invite automatiquement mise à jour dans votre répertoire actuel:

prompt_command () {
    PS1='$(basename $(dirname "$PWD"))/$(basename "$PWD") $ '
}
PROMPT_COMMAND=prompt_command
twalbaum
la source
1
La définition est-elle prompt_command()censée faire quelque chose à elle seule? Ce n'est pas pour moi. Vouliez-vous également l'utiliser prompt_command()dans les redéfinitions de cd& co, comme Gilles l'a fait? Ou tu voulais dire PROMPT_COMMAND='...'?
LarsH
2
En outre, cette commande échoue lorsqu'elle $PWDcontient un espace.
LarsH
1
Merci de me ramener à cela. A cité les $ PWD pour permettre des espaces et a inclus la commande finale. Mon invite actuelle est plus complexe que cela, d'où la nécessité de la définition de prompt_command. Sinon, PS1 = ... fonctionne de manière active.
twalbaum
Des idées pour nettoyer la sortie lors de la navigation vers /? Comme écrit, vous obtenez/// $
ezrock
0

La chaîne d'invite peut être facilement modifiée en bashmodifiant la variable shell PS1. Cela signifie Prompt String 1. Plus d'informations ici .

Pour l'instant, lancez votre bashcoquille.

vi ~/.bashrc

Ajoutez la définition PS1 dans le fichier

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

Plus de tutoriels ici et ici , pour vous aider à le peaufiner encore plus.

Munai Das Udasin
la source
1
Je comprends comment modifier l'invite. Ma question est de savoir comment obtenir uniquement les répertoires courant et parent, pas le chemin complet.
twalbaum
@twalbaum a modifié ma réponse
Munai Das Udasin
heureux d'aider @twalbaum :)
Munai Das Udasin
1
Cela définit l'invite sur le répertoire courant au moment du .bashrcchargement, l'invite ne changera pas si vous cddans un autre répertoire! @twalbaum
Gilles 'SO- arrête d'être méchant'
@Gilles, ça le fait pour moi.
twalbaum
0

Peut être plus simple avec "~" pour le répertoire d'accueil.

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