En regardant ce fil génial j’ai remarqué que certains exemples utilisent
PS1="Blah Blah Blah"
et certains utilisent
Prompt_COMMAND="Blah Blah Blah"
(et certains utilisent les deux) lors du réglage de l'invite dans un shell bash. Quelle est la différence entre les deux? Une recherche SO et même un peu de recherche google plus large ne m'obtiennent pas de résultats, alors même un lien vers le bon endroit pour chercher la réponse serait apprécié.
Depuis la page du document GNU Bash: http://www.gnu.org/software/bash/manual/bashref.html
Prompt_COMMAND
If set, the value is interpreted as a command to execute before
the printing of each primary Prompt ($PS1).
Je ne l'ai jamais utilisé, mais j'aurais pu l'utiliser à l'époque où je n'avais que sh.
Prompt_COMMAND peut contenir des instructions bash ordinaires, tandis que la variable PS1 peut également contenir les caractères spéciaux, tels que "\ h" pour le nom d'hôte, dans la variable.
Par exemple, voici mon invite bash qui utilise Prompt_COMMAND et PS1. Le code bash de Prompt_COMMAND détermine la branche git dans laquelle vous vous trouvez et l’affiche à l’invite, ainsi que le statut de sortie du dernier processus exécuté, le nom d’hôte et le nom de base du mot de passe. La variable RET stocke la valeur de retour du dernier programme exécuté. C'est pratique pour voir s'il y a une erreur et le code d'erreur du dernier programme que j'ai exécuté dans le terminal. Notez le 'entourant l'expression entière Prompt_COMMAND. Il inclut PS1 pour que cette variable soit réévaluée chaque fois que la variable Prompt_COMMAND est évaluée.
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";'
L'exemple de sortie ressemble à ceci dans un répertoire non-git:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
et dans un répertoire git, vous voyez le nom de la branche:
sashan@dhcp-au-122 rework mybranch $
Après avoir lu les commentaires et la réponse de Bob, je pense que l'écrire comme il le décrit est préférable. Il est plus facile à gérer que ce que j'avais initialement écrit ci-dessus, où la variable PS1 est définie dans Prompt_COMMAND, qui est une chaîne extrêmement compliquée qui est évaluée à l'exécution par bash. Cela fonctionne, mais c'est plus compliqué que nécessaire. Pour être juste, j’ai écrit Prompt_COMMAND pour moi-même il ya environ 10 ans et cela a fonctionné et n’y a pas trop réfléchi.
Pour ceux qui sont curieux de savoir comment j'ai modifié mes modifications, j'ai essentiellement mis le code de Prompt_COMMAND dans un fichier séparé (comme Bob l'a décrit), puis répercuté la chaîne que j'ai l'intention d'être 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"
et dans mon .bashrc
function Prompt_command {
RET=$?
export PS1=$(~/.bash_Prompt_command $RET)
}
Prompt_DIRTRIM=3
export Prompt_COMMAND=Prompt_command
La différence est que PS1 est la chaîne d'invite réellement utilisée et Prompt_COMMAND, une commande exécutée juste avant l'invite. Si vous voulez le moyen le plus simple et le plus flexible de créer une invite, essayez ceci:
Mettez ceci dans votre .bashrc:
function Prompt_command {
export PS1=$(~/bin/bash_Prompt)
}
export Prompt_COMMAND=Prompt_command
Ensuite, écrivez un script (bash, Perl, Ruby: votre choix) et placez-le dans ~/bin/bash_Prompt.
Le script peut utiliser toutes les informations qu'il souhaite pour construire une invite. C'est beaucoup plus simple parce que vous n'avez pas à apprendre le langage de substitution quelque peu baroque qui a été développé uniquement pour la variable PS1.
Vous pourriez penser que vous pourriez faire la même chose en définissant simplement Prompt_COMMAND directement sur ~/bin/bash_Prompt et en définissant PS1 sur la chaîne vide. Au début, cela semble fonctionner, mais vous découvrez rapidement que le code de la readline s'attend à ce que PS1 soit défini sur l'invite réelle et, lorsque vous faites défiler les mots clés de l'historique, tout est gâché. Cette solution de contournement fait en sorte que PS1 reflète toujours la dernière invite (car la fonction définit la valeur PS1 réelle utilisée par l'instance invoquante du shell), ce qui facilite le fonctionnement de l'historique de lecture et de commande.
De man bash
:
Prompt_COMMAND
Si elle est définie, la valeur est exécutée en tant que commande avant l'émission de chaque invite principale.
PS1
La valeur de ce paramètre est développée (voir PROMPTING ci-dessous) et utilisée comme chaîne d'invite principale. La valeur par défaut est ''\s-\v\$ ''.
Si vous voulez simplement définir la chaîne d'invite, utiliser PS1
seul est suffisant:
PS1='user \u on Host \h$ '
Si vous voulez faire autre chose juste avant d'imprimer l'invite, utilisez Prompt_COMMAND
. Par exemple, si vous souhaitez synchroniser les écritures mises en cache sur le disque, vous pouvez écrire:
Prompt_COMMAND='sync'
Oui, alors essayez vraiment de bien comprendre:
Prompt_COMMAND
est une pratique bash commodité/fonction pratique, mais il n’ya rien à proprement parler qui ne puisse également être utilisé avec PS1
seul, correct?Je veux dire, si on veut définir une autre variable avec une étendue en dehors de l'invite: selon le shell, cette variable devra probablement être déclarée première en dehors de $PS1
ou (pire des cas), avoir envie de quelque chose en attente d'un FIFO avant d'appeler $PS1
(et de se réarmer à la fin de $PS1
); le \u
\h
peut causer des problèmes, surtout si vous utilisez des expressions rationnelles sophistiquées; mais sinon: on peut accomplir tout ce que Prompt_COMMAND
peut faire en utilisant la substitution de commande dans $PS1
(et, éventuellement, dans certains cas, des sous-shell explicites)?
Droite?
la différence est que
Prompt_COMMAND
, cela affichera votre invite bashPS1
remplace \H
et ses amisPrompt_COMMAND
exécute son contenu, PS1
utilise son contenu comme invite.PS1
effectue une expansion de variable et une substitution de commande à chaque invite. Il n'est donc pas nécessaire d'utiliser Prompt_COMMAND
pour attribuer une valeur à PS1
ou pour exécuter du code arbitraire. vous pouvez facilement faire export PS1='$(uuidgen) $RANDOM'
une fois dans .bash_profile
, utilisez simplement des guillemets simples