PROMPT_COMMAND pode conter instruções bash comuns, enquanto a variável PS1 também pode conter os caracteres especiais, como '\ h' para o nome do host, na variável.
Por exemplo, aqui está meu prompt bash que usa PROMPT_COMMAND e PS1. O código bash em PROMPT_COMMAND calcula em qual branch git você está e o exibe no prompt, junto com o status de saída do último processo executado, nome do host e nome de base do pwd. A variável RET armazena o valor de retorno do último programa executado. Isso é conveniente para ver se houve um erro e o código de erro do último programa que executei no terminal. Observe o 'externo em torno de toda a expressão PROMPT_COMMAND. Inclui PS1 para que esta variável seja reavaliada cada vez que a variável PROMPT_COMMAND for avaliada.
PROMPT_COMMAND='RET=$?;\
BRANCH="";\
ERRMSG="";\
if [[ $RET != 0 ]]; then\
ERRMSG=" $RET";\
fi;\
if git branch &>/dev/null; then\
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2);\
fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'
A saída de exemplo fica assim em um diretório não git:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
e em um diretório git você vê o nome do branch:
sashan@dhcp-au-122 rework mybranch $
Atualizar
Depois de ler os comentários e a resposta de Bob, acho que é melhor escrever como ele descreve. É mais sustentável do que o que escrevi originalmente acima, onde a variável PS1 é definida dentro do PROMPT_COMMAND, que por si só é uma string supercomplicada que é avaliada em tempo de execução pelo bash. Funciona, mas é mais complicado do que precisa ser. Para ser justo, eu escrevi esse PROMPT_COMMAND para mim há cerca de 10 anos e funcionou e não pensei muito sobre isso.
Para aqueles que estão curiosos para saber como eu alterei minhas coisas, basicamente coloquei o código para o PROMPT_COMMAND em um arquivo separado (como Bob descreveu) e, em seguida, ecoa a string que pretendo ser PS1:
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour
if [ -z $SCHROOT_CHROOT_NAME ]; then
SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
ERRMSG=" $RET"
fi
if which git &>/dev/null; then
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2)
else
BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"
e no meu .bashrc
function prompt_command {
RET=$?
export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
if git branch &>/dev/null ; then\
. Ele redireciona stdout e stderr para / dev / null. tldp.org/LDP/abs/html/io-redirection.htmlPROMPT_COMMAND
.Don't set PS1 in PROMPT_COMMAND! Set variables in PROMPT_COMMAND and use them in PS1
PS1
online dentroPROMPT_COMMAND
é desvantajoso. É um código perfeitamente útil. Em contraste com a resposta de Bob para baixo, aPS1
variável foi construída corretamente. Isso permite um prompt bash muito mais sofisticado, dependendo da sua situação real.PS1
interna de @ChristianWolfPROMPT_COMMAND
não serve para nada. é um exemplo de como não fazer. construirPS1
uma vez.bash_profile
, apenas use aspas simples em vez de aspas duplas, para que as substituições de variáveis sejam avaliadas durante cada prompt.A diferença é que PS1 é a string de prompt real usada e PROMPT_COMMAND é um comando executado logo antes do prompt. Se você deseja a maneira mais simples e flexível de construir um prompt, tente o seguinte:
Coloque isso em seu .bashrc:
Em seguida, escreva um script (bash, perl, ruby: sua escolha) e coloque-o em ~ / bin / bash_prompt.
O script pode usar qualquer informação que desejar para construir um prompt. Isso é IMO muito mais simples porque você não precisa aprender a linguagem de substituição um tanto barroca que foi desenvolvida apenas para a variável PS1.
Você pode pensar que poderia fazer o mesmo simplesmente definindo PROMPT_COMMAND diretamente para ~ / bin / bash_prompt e definindo PS1 para a string vazia. A princípio, isso parece funcionar, mas você logo descobre que o código readline espera que o PS1 seja configurado para o prompt real e, quando você rola as palavras para trás no histórico, as coisas ficam confusas como resultado. Essa solução alternativa faz com que o PS1 sempre reflita o prompt mais recente (uma vez que a função define o PS1 real usado pela instância de chamada do shell), e isso faz com que a linha de leitura e o histórico de comandos funcionem bem.
fonte
PS1
emPROMPT_COMMAND
! Defina variáveis emPROMPT_COMMAND
e use-as emPS1
. Caso contrário, você perderá a capacidade de usar asPS1
sequências de escape como\u
ou\h
. Você tem que reinventá-losPROMPT_COMMAND
. Isso pode ser possível, mas não é possível contornar a perda\[
e\]
que marcam o início e o fim dos caracteres não imprimíveis. Isso significa que você não pode usar cores sem confundir o terminal sobre o comprimento do prompt. E isso confundereadline
ao editar um comando que gera duas linhas. No final, você tem uma grande bagunça na tela.PROMPT_COMMAND
é executado antes da impressãoPS1
. Não vejo problemas de configuraçãoPS1
por dentroPROMPT_COMMAND
, pois depois dePROMPT_COMMAND
finalizado, o shell irá imprimirPS1
, o que foi modificadoPROMPT_COMMAND
(ou neste caso, por dentroprompt_command
)?export PS1='$(~/bin/bash_prompt)'
faz a mesma coisa bug parece normalDe
man bash
:Se você simplesmente deseja definir a string do prompt, usar
PS1
sozinho é o suficiente:Se quiser fazer outra coisa antes de imprimir o prompt, use
PROMPT_COMMAND
. Por exemplo, se você deseja sincronizar gravações em cache para o disco, pode escrever:fonte
PS1
sem a necessidadePROMPT_COMMAND
, pois a sequência que define o título pode ser incluídaPS1
entre\[
e\]
.PS1
, ela apenas será definida no subshell, então você não pode obter seu valor de volta. mas seu exemplo é trivialPS1='$(sync)user \u on host \h$ '
a diferença é que
PROMPT_COMMAND
, irá estragar seu prompt bashPS1
substitutos\H
e amigosPROMPT_COMMAND
executa seu conteúdo,PS1
usa seu conteúdo como prompt.PS1
faz expansão de variável e substituição de comando em cada prompt, sem necessidade de usarPROMPT_COMMAND
para atribuir valorPS1
ou executar código arbitrário. você pode fazer facilmenteexport PS1='$(uuidgen) $RANDOM'
uma vez.bash_profile
, basta usar aspas simplesfonte
Sim, para tentar realmente acertar:
PROMPT_COMMAND
é uma função / variável de conveniência bash útil , mas não há, estritamente falando, nada que também não possa ser feitoPS1
sozinho, correto?Quero dizer, se alguém deseja definir outra variável com escopo fora do prompt: dependendo do shell, essa variável provavelmente precisaria ser declarada primeiro fora
$PS1
ou (pior caso), pode-se ter que imaginar algo esperando em um FIFO antes de chamando$PS1
(e armado novamente no final de$PS1
); o\u
\h
pode causar alguns problemas, especialmente se você estiver usando alguma fantasia regex; mas caso contrário: pode-se realizar qualquer coisaPROMPT_COMMAND
usando a substituição de comando dentro$PS1
(e, talvez em casos extremos, subshells explícitos)?Certo?
fonte