Mostrar apenas o diretório atual e o pai no prompt do bash

16

Eu sou novo no bash e gostaria que meu prompt mostrasse algo que no tcsh era trivial, mas depois de uma boa pesquisa no google ainda não consigo fazer.

Gostaria que meu prompt incluísse apenas os diretórios atual e pai como este:

/parent/currentdir $

No tcsh, isso é alcançado por:

set prompt = "%C2 %"

No entanto, no bash até agora, só descobri que tenho que analisar o pwd para obter a mesma saída.

Não existe uma maneira mais simples, como fazer:

export PS1="$(some_command) $" 
twalbaum
fonte
2
Em teoria, PS1='\w \$'; PROMPT_DIRTRIM=2deve fornecer o equivalente ao bash, mas isso não funciona corretamente no meu sistema.
Mikel
Não funciona de jeito nenhum no meu: GNU bash, versão 3.2.57 (1) -release (x86_64-apple-darwin14).
Twalbaum
PROMPT_DIRTRIMfoi introduzido no Bash 4 . Acabei de testar no Ubuntu 16.04 sob WSL e funcionou muito bem!
Mike Branski

Respostas:

18

Os recursos de controle de prompt do Bash são bastante estáticos. Se você quiser mais controle, poderá incluir variáveis ​​em seu prompt; verifique se você não desativou a promptvarsopção .

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

Observe as aspas simples: as expansões da variável devem ocorrer no momento em que o prompt é exibido, não no momento em que a PS1variável é definida.

Se você deseja ter mais controle sobre o que é exibido, pode usar substituições de comando. Por exemplo, o trecho acima perde a ~abreviação do diretório inicial.

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

Este código é um pouco complicado, então em vez de furá-lo para a PS1variável, você pode usar a PROMPT_COMMANDvariável para executar o código de conjunto HPWDe, em seguida, usar isso em seu prompt.

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

Como o prompt reduzido só foi alterado em uma alteração de diretório, você não precisa recalculá-lo sempre que um prompt é exibido. O Bash não fornece um gancho que é executado em uma alteração de diretório atual, mas você pode simulá-lo substituindo cdseus primos.

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

Observe que você não precisa exportar e não deve exportar PS1 , pois é uma configuração de shell, não uma variável de ambiente. Uma PS1configuração do bash não seria entendida por outras conchas.

PS Se você deseja uma boa experiência de shell interativa, mude para zsh , onde todos esses ( %expansões rápidas que abrangem amplamente o tcsh chpwd, etc.) são recursos nativos.

PS1='%2~ %# '
Gilles 'SO- parar de ser mau'
fonte
2
Essa deveria ter sido a resposta aceita e mais votada.
Larsh
3

A sintaxe para obter os diretórios pai e atual é extraída do arquivo Munai resposta .

No entanto, como observado por Gilles, esse código mostra apenas o diretório atual no momento .bashrc é carregado, mas não muda conforme você navega no sistema para outras pastas.

Tendo isso em seu .bashrcarquivo, o prompt é atualizado automaticamente para o diretório atual:

prompt_command () {
    PS1='$(basename $(dirname "$PWD"))/$(basename "$PWD") $ '
}
PROMPT_COMMAND=prompt_command
twalbaum
fonte
1
Definir é prompt_command()suposto fazer algo por si só? Não é para mim. Você queria usar também prompt_command()nas redefinições de cd& co, como Gilles? Ou você quis dizer PROMPT_COMMAND='...'?
Larsh
2
Além disso, este comando falha quando $PWDcontém um espaço.
precisa saber é o seguinte
1
Obrigado por me trazer de volta a isso. Citou os $ PWDs para permitir espaços e incluiu o comando final. Meu prompt atual é mais complexo que isso, portanto, a necessidade da definição do prompt_command. Caso contrário, PS1 = ... funciona.
twalbaum
Alguma idéia para limpar a saída ao navegar para /? Como está escrito, você recebe/// $
ezrock 10/11
0

A sequência de prompt pode ser facilmente alterada basheditando a variável shell PS1. Significa Prompt String 1. Mais informações aqui .

Por enquanto, ative sua bashconcha.

vi ~/.bashrc

Anexe a definição PS1 no arquivo

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

Mais tutoriais aqui e aqui , para ajudá-lo a ajustá-lo ainda mais.

Munai Das Udasin
fonte
1
Eu entendo como modificar o prompt. Minha pergunta é como obter apenas os diretórios atual e pai, não o caminho inteiro.
Twalbaum 18/07/2015
@twalbaum editado minha resposta
Munai Das Udasin
Fico feliz em ajudar @twalbaum :)
Munai Das Udasin
1
Isso define o prompt para o diretório atual no momento em que .bashrcé carregado; o prompt não será alterado se você cdentrar em outro diretório! @twalbaum
Gilles 'SO- stop
@ Gilles faz por mim.
Twalbaum 19/07
0

Pode ser mais simples com "~" para o diretório Home.

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