Показывать только текущее имя каталога (не полный путь) в приглашении bash


71

Способ, которым моя подсказка bash настроена в настоящее время, показывает полный путь к текущему каталогу. Это раздражает, когда я глубоко в дереве каталогов, так как приглашение становится настолько длинным, что каждая команда переносится в следующую строку. Как мне сделать так, чтобы он показывал только последнюю часть пути?

Вот что я имею в своем .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

Ответы:


98

Измените \w(нижний регистр) на \W(верхний регистр):

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

Загляните в Bash Prompt HOWTO, чтобы узнать больше интересных деталей. пример:

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_COMMANDПеременное, если установлена, является командой , которая получает запустить перед отображением строки , указанной в PS1. В вашем случае PROMPT_COMMANDвыполняется echoоператор с определенными escape-последовательностями ANSI, которые манипулируют заголовком Xterm .

Если вы подозреваете, что PROMPT_COMMANDваш PS1запрос переопределен , вы можете unsetпроверить его и проверить:

$ unset PROMPT_COMMAND

Наконец, убедитесь, что вы меняете PS1определение, которое фактически используется. Общие места являются /etc/bash.bashrc, /etc/profile, ~/.bashrc, ~/.bash_profile, ~/.profile. Системные файлы обычно (но не всегда) запускаются перед пользовательскими файлами.


Хм ... Боюсь, что это уже \ w, но кажется, что это caseзаявление переопределяет его, когда я нахожусь на xterm, и проблема, кажется, PWDв PROMPT_COMMANDстроке. Ты знаешь, что я должен положить туда?
hsribei

4
\w(нижний регистр) устанавливает полный путь, \W(верхний регистр) обрезает последний бит. PROMPT_COMMAND устанавливает заголовок окна в xterm. проверьте переменную TERM; если он не начинается с «xterm» или «rxvt», то PROMPT_COMMAND даже не запускается.
Квик-кихот

О да, да. Извините, я смешал прописные и строчные буквы. Это сработало. Спасибо! :)
hsribei

Отличный ответ. Убедитесь, что вы перезагрузитесь, чтобы это вступило в силу. Спасибо!
Объединить

14

Простая команда замены bash

${VAR/pattern_to_find/pattern_to_replace}

Для показа последнего каталога, который вы можете просто сделать ${PWD/*\//}, то есть найти что-либо раньше, включая последний, ' /' и заменить его ничем.

На моей машине с Ubuntu я использую:

export PS1='$(whoami):${PWD/*\//}#'. 

1
Мне нравится этот ответ лучше, чем принятый, потому что он является общим для любой ситуации, а не просто специальной логикой синтаксического анализа в $ PS1. Меньше более мощных инструментов легче запомнить и составить. :)
Дэвид Эллис

4

Мое решение состоит в том, чтобы показать три верхних и два нижних каталога, когда их более 5

Так что мое приглашение (в котором есть и другая информация) выглядит так:

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

когда мой pwd на самом деле

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

Моя подсказка PS1 настроена следующим образом:

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 это функция, которая показывает текущую ветку git, я храню ее в своих точечных файлах, это:

git_branch () {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
  }

Это круто! Большое спасибо за этот ответ.
Карлос Ф

4

Мое решение для этого немного отличается в отношении того, как я могу его экспортировать, поэтому я поделился этим здесь:

Создайте другую строковую переменную подсказки; PS5 и экспортируйте следующую строку в ваш .profile/ .bash_profileфайл:

\ u : Показать текущее имя пользователя.

\ W : Распечатать базу текущего рабочего каталога.

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

Теперь, когда вам нужно использовать сокращенное PS, просто запустите: eval $PS5


Или еще лучше, создайте псевдоним в вашем .bash_aliasesфайле: (спасибо @muru )

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

sourceснова, и теперь вы можете просто напечатать PS5для переключения.


1
Это похоже на frankenalias. Почему бы просто не использовать псевдоним или функцию?
Муру

1

Показывать только текущее имя каталога (не полный путь) в приглашении bash

Большинство других решений не работали для меня во всех моих ОС, которые используют мои точечные файлы: AIX, Windoze и Linux. Порты Баш были старые версии , которые не поддерживают определенные конструкции , и я не хочу , чтобы отвалить другой процесс (то есть sed, awkи т.д.) , которая заметно дороже под Cygwin.

Следующее долго, но производительно:

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

Хочу выплюнуть

/
/usr
/usr/foo
foo/bin

Обратите внимание на отсутствие косой черты в последней строке, что мне нравится. Кроме того, вы можете выплюнуть последние 3 каталога, изменив arg на DIR_LAST.

Кроме того, я пытался сделать это с помощью регулярных выражений, BASH_REMATCHно bash v3, похоже, не нравился паренам, и я не мог понять, как правильно их избежать. Вздох.


0

Я считаю, что этот вариант намного проще, просто сделав:

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

Поэтому присвойте это переменной PS1 в вашем файле .bashrc:

PS1='$(PWD | rev | cut -d '/' -f 1 | rev)'

0
root:~/project#  -> root:~/project(dev)# 

добавьте следующий код в конец вашего ~ / .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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.