Pokaż tylko bieżącą nazwę katalogu (nie pełną ścieżkę) w wierszu polecenia bash

71

Sposób, w jaki aktualnie konfigurowany jest mój monit bash, pokazuje całą ścieżkę do bieżącego katalogu. Jest to denerwujące, gdy jestem głęboko w drzewie katalogów, ponieważ monit staje się tak długi, że każde polecenie zawija się do następnego wiersza. Jak sprawić, by pokazywał tylko ostatnią część ścieżki?

Oto co mam w swoim .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
źródło

Odpowiedzi:

98

Zmień \w(małe litery) na \W(wielkie litery):

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

Zajrzyj do Bash Prompt HOWTO, aby uzyskać wiele zabawnych szczegółów. przykład:

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$

PROMPT_COMMANDZmienna, jeśli jest ustawiona, to polecenie, które zostanie uruchomiony przed wyświetleniem monitu określonego w PS1. W twoim przypadku PROMPT_COMMANDuruchamia echoinstrukcję z pewnymi sekwencjami ucieczki ANSI, które manipulują paskiem tytułowym Xterm .

Jeśli podejrzewasz, że PROMPT_COMMANDprzesłaniasz PS1monit, możesz to unsetzrobić i przetestować:

$ unset PROMPT_COMMAND

Na koniec upewnij się, że zmieniasz PS1definicję, która faktycznie jest używana. Typowe lokalizacje są /etc/bash.bashrc, /etc/profile, ~/.bashrc, ~/.bash_profile, ~/.profile. Pliki systemowe są generalnie (ale nie zawsze) uruchamiane przed plikami użytkownika.

quack quixote
źródło
Hm ... Obawiam się, że to już \ W, ale wydaje się, że caseoświadczenie zastępuje go, gdy jestem na xterm, a problem wydaje się być z PWDw PROMPT_COMMANDlinii. Czy wiesz co powinienem tam umieścić?
hsribei
4
\w(małe litery) ustawia go na pełną ścieżkę, \W(wielkie litery) przycina do ostatniego bitu. PROMPT_COMMAND ustawia tytuł okna w xterm. sprawdź swoją zmienną TERM; jeśli nie zaczyna się od „xterm” lub „rxvt”, to PROMPT_COMMAND nawet się nie uruchamia.
quack quixote
Och tak. Przepraszam, pomieszałem wielkie i małe litery. To się udało. Dzięki! :)
hsribei,
Świetna odpowiedź. Uruchom ponownie, aby to zadziałało. Dzięki!
Połącz
14

Proste polecenie zamiany bash jest

${VAR/pattern_to_find/pattern_to_replace}

Aby wyświetlić ostatni katalog, możesz po prostu zrobić ${PWD/*\//}, tj. Znaleźć dowolną rzecz przed ostatnim, włączając w to ostatni „ /” i zastąpić go niczym.

Na mojej maszynie ubuntu używam:

export PS1='$(whoami):${PWD/*\//}#'. 
stopBugs
źródło
1
Podoba mi się ta odpowiedź bardziej niż zaakceptowana, ponieważ jest ogólna w każdej sytuacji zamiast tylko specjalnej logiki parsowania $ PS1. Mniej mocniejszych narzędzi jest łatwiejszych do zapamiętania i komponowania. :)
David Ellis
4

Moim rozwiązaniem jest wyświetlenie górnych trzech i dolnych 2 katalogów, gdy jest ich więcej niż 5

Mój monit (który zawiera także inne informacje) wygląda następująco:

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

kiedy faktycznie jest mój pwd

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

Mój monit PS1 jest konfigurowany w następujący sposób:

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 jest funkcją, która pokazuje bieżącą gałąź git, trzymam ją w moich plikach dot, jest to:

git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
  }
Michael Durrant
źródło
To jest niesamowite! Wielkie dzięki za tę odpowiedź.
Carlos F
4

Moje rozwiązanie tego problemu różni się nieco pod względem eksportu, więc pomyślałem, że podzielę się tutaj:

Utwórz kolejną zmienną ciągu zachęty; PS5 i wyeksportuj następujący ciąg do pliku .profile/ .bash_profile:

\ u : wyświetl aktualną nazwę użytkownika.

\ W : Wydrukuj bazę bieżącego katalogu roboczego.

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

Teraz, gdy potrzebujesz użyć skróconego PS, po prostu uruchom: eval $PS5


Lub jeszcze lepiej, utwórz alias w swoim .bash_aliasespliku: (dzięki @muru )

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

sourceponownie, a teraz możesz po prostu wpisać, PS5aby przełączyć.

U-sposoby
źródło
1
To wygląda jak frankenalias. Dlaczego nie użyć tylko aliasu lub funkcji?
muru
1

Pokaż tylko bieżącą nazwę katalogu (nie pełną ścieżkę) w wierszu polecenia bash

Większość innych rozwiązań nie działała dla mnie we wszystkich moich systemach operacyjnych, które współużytkują moje pliki kropek: AIX, Windoze i Linux. Porty bash były stare wersje, które nie obsługują niektóre konstrukcje i nie chcą bulić inny proces (tj sed, awketc.), która jest zauważalnie droższe pod Cygwin.

Poniższe jest długie, ale wydajne:

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

Chcę, żeby wypluł:

/
/usr
/usr/foo
foo/bin

Zwróć uwagę na brak wiodącego ukośnika w ostatnim wierszu, który mi się podoba. Możesz także wypluć ostatnie 3 katalogi, zmieniając argument na DIR_LAST.

Ponadto próbowałem to zrobić za pomocą wyrażenia regularnego, BASH_REMATCHale bash v3 nie wydawał się lubić parenów i nie mogłem wymyślić, jak właściwie z nich uciec. Westchnienie.

Szary
źródło
0

Wierzę, że ta opcja jest znacznie łatwiejsza, po prostu wykonując:

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

Więc przypisz to do zmiennej PS1 w pliku .bashrc:

PS1='$(PWD | rev | cut -d '/' -f 1 | rev)'
Dani Mach
źródło
0
root:~/project#  -> root:~/project(dev)# 

dodaj następujący kod na końcu swojego ~ / .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
źródło