Показуйте лише поточний та батьківський каталог у запиті bash


16

Я новачок у баші та хотів би, щоб мої підказки показали щось, що в tcsh було тривіально, але після гарного пошуку в Google я все ще не можу зробити.

Я б хотів, щоб моє запрошення включало лише поточні та батьківські каталоги на зразок цього:

/parent/currentdir $

У tcsh це досягається:

set prompt = "%C2 %"

Однак в bash поки що я виявив, що мені потрібно розібрати pwd, щоб отримати той самий вихід.

Чи не існує простішого способу, як це зробити:

export PS1="$(some_command) $" 

2
Теоретично, PS1='\w \$'; PROMPT_DIRTRIM=2слід дати вам еквівалент bash, але це не працює належним чином у моїй системі.
Мікель

Він не працює на моєму: GNU bash, версія 3.2.57 (1) -release (x86_64-apple-darwin14).
twalbaum

PROMPT_DIRTRIMбуло введено в Bash 4 . Я щойно тестував на Ubuntu 16.04 під WSL, і він працював чудово!
Майк Бранський

Відповіді:


18

Функції швидкого керування Баша доволі статичні. Якщо ви хочете більше контролю, ви можете включити змінні у своє запит; переконайтеся, що ви не відключили цю promptvarsопцію .

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

Зверніть увагу на одиничні лапки: розширення змінної має відбуватися під час відображення підказки, а не в момент визначення PS1змінної.

Якщо ви хочете більше контролювати те, що відображається, ви можете використовувати підстановки команд. Наприклад, вищевказаний фрагмент втрачає ~абревіатуру для домашнього каталогу.

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

Цей код досить громіздкий, тому замість того, щоб вставляти його у PS1змінну, ви можете використовувати PROMPT_COMMANDзмінну для запуску коду для встановлення, HPWDа потім використовувати його у своєму запиті.

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

Оскільки скорочений рядок змінився лише під час зміни каталогу, вам не потрібно перераховувати його щоразу, коли відображається запит. Bash не забезпечує гачок, який працює на поточній зміні каталогу, але ви можете імітувати його за допомогою переосмислення cdта його двоюрідних братів.

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

Зауважте, що вам не потрібно і не слід експортувати PS1, оскільки це налаштування оболонки, а не змінна середовище. PS1Інші оболонки не можуть зрозуміти баш- налаштування.

PS Якщо ви хочете насолодитись інтерактивним досвідом оболонки, перейдіть на zsh , де всі ці (швидкі %розширення, що значною мірою охоплюють tcsh, chpwdі т. Д.) Є натільними особливостями.

PS1='%2~ %# '

2
Це повинна була бути прийнятою і найбільш схвальною відповіддю.
LarsH

3

Синтаксис отримання батьківського та поточного каталогів взято з відповіді Муная .

Однак, як зазначає Жилл, цей код показує лише завантажену в даний момент каталог .bashrc, але він не змінюватиметься, коли ви переходите до інших папок.

Якщо це у вашому .bashrcфайлі, запит автоматично оновлюється до поточного каталогу:

prompt_command () {
    PS1='$(basename $(dirname "$PWD"))/$(basename "$PWD") $ '
}
PROMPT_COMMAND=prompt_command

1
Чи визначає, prompt_command()чи потрібно щось робити самостійно? Це не для мене. Ви мали на увазі також використання prompt_command()у перегляді cd& co, як це робив Жил? Або ти мав на увазі PROMPT_COMMAND='...'?
LarsH

2
Також ця команда виходить з ладу, коли $PWDмістить пробіл.
LarsH

1
Дякую, що повернули мене до цього. Котирував $ PWD, щоб забезпечити пробіли, і включив остаточну команду. Мій поточний запит є більш складним, ніж це, тому необхідність визначення prompt_command. В іншому випадку PS1 = ... працює над його включенням.
twalbaum

Будь-які ідеї для очищення вихідних даних під час навігації /? Як написано, ви отримуєте/// $
ezrock

0

Рядок підказок можна легко змінити bash, редагуючи змінну оболонки PS1. Це розшифровка рядка підказок 1. Детальніше тут .

Поки що підпаліть bashснаряд.

vi ~/.bashrc

Додайте визначення файлу PS1 у файл

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

Більше навчальних посібників тут і тут , щоб допомогти вам підправити його ще більше.


1
Я розумію, як змінити підказку. Моє запитання - як отримати лише поточні та батьківські каталоги, а не весь шлях.
twalbaum

@twalbaum відредагував мою відповідь
Munai Das Udasin

Рада допомогти @twalbaum :)
Munai Das Udasin

1
Це встановлює підказку для поточного каталогу під час .bashrcзавантаження, запит не зміниться, якщо ви перейдете cdв інший каталог! @twalbaum
'SO- перестань бути злом'

@Gilles це робить для мене.
twalbaum

0

Може бути простішим з "~" для домашнього каталогу.

function PWDN {
  echo "${PWD/#$HOME/~}" | rev | cut -d "/" -f1 -f2 | rev
}

0
export PS1='[\u@\h $(basename $(dirname ${PWD}))/$(basename ${PWD})]\$ '
export PROMPT_COMMAND='echo -ne "\033]0;$(basename $(dirname $PWD))/$(basename ${PWD})\007"'

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.