41 votes

Quel est l'équivalent ZSH de $PROMPT_COMMAND de BASH?

BASH prend en charge une variable d'environnement $PROMPT_COMMAND qui définit une commande à exécuter avant tout premier niveau d'invite interactive. Je recherche l'équivalent de cela pour ZSH.

La documentation indique qu'il existe une fonction precmd que je peux définir pour y parvenir ; cependant, je ne sais pas comment la définir à partir d'une variable d'environnement.

J'ai envisagé de passer une variable d'environnement qui ferait en sorte que ZSH lise un fichier contenant la définition de cette fonction, mais ZSH ne semble pas prendre en charge de telles choses : il lit uniquement des fichiers globaux puis des fichiers par utilisateur. Je peux les remplacer mais je ne peux pas y ajouter sans modifier les fichiers, ce que je ne peux pas faire.

Alors comment définir un accroche avant l'invite de commande dans ZSH via une variable d'environnement, comme je le ferais en utilisant $PROMPT_COMMAND dans BASH ?

37voto

mpy Points 24817

La méthode la plus simple pour émuler $PROMPT_COMMAND de bash qui me vient à l'esprit est d'utiliser le crochet precmd, comme vous l'avez déjà compris. Définissez-le comme suit :

precmd() { eval "$PROMPT_COMMAND" }

et vous pouvez faire quelque chose comme ça :

$ PROMPT_COMMAND='echo Bonjour, il est actuellement $(date)'
Bonjour, il est maintenant Lun, Mar 31, 2014 7:08:00 PM
$ whoami      
utilisateur
Bonjour, il est maintenant Lun, Mar 31, 2014 7:08:21 PM     
$

Veuillez noter les simples guillemets dans cet exemple, sinon $(date) sera étendu trop tôt, c'est-à-dire déjà lors de la définition de $PROMPT_COMMAND et non lors de l'appel avant l'invite.


Si vous souhaitez préserver (et ne pas modifier) la définition existante, vous pouvez utiliser cette approche :

$ prmptcmd() { eval "$PROMPT_COMMAND" }
$ precmd_functions=(prmptcmd)

Ainsi, la fonction prmptcmd est exécutée après la fonction precmd() existante.


Enfin, voici une manière adaptée à une utilisation dans un package logiciel, qui ne devrait ni modifier les fichiers utilisateur ou système, ni entrer les commandes de manière interactive.

Un exemple pour démarrer une session bash pourrait être :

PROMPT_COMMAND="echo foo" bash

Pour démarrer zsh, vous pouvez utiliser :

ZDOTDIR=/répertoire/du/programme zsh

ce qui provoque la lecture de /répertoire/du/programme/.zshrc. Dans ce fichier, le crochet precmd() peut être défini comme expliqué ci-dessus. Si vous voulez inclure les paramètres de l'utilisateur en plus, incluez également source $HOME/.zshrc, etc. dans le .zshrc du programme. Cette configuration est maintenable, car aucun fichier en dehors du répertoire du programme n'est modifié.


En guise de dernière addition, voici une preuve de concept sur la façon de conserver le message de bienvenue newuser. Utilisez le code suivant dans votre fichier de configuration rc /répertoire/du/programme/.zshenv :

echo définir precmd, traps, etc.

autoload -Uz zsh-newuser-install

if [[ ! -e "$HOME/.zshrc" ]]; then
  zsh-newuser-install -f
  mv $ZDOTDIR/.zshrc $HOME/.zshrc
else
  builtin source $HOME/.zshrc
fi

9voto

Sneftel Points 101

Tel que le mentionne @mypy, la fonction precmd de Zsh fonctionne de manière similaire à PROMPT_COMMAND de Bash.

Voici un exemple qui fonctionne pour Bash ou Zsh et n'utilise pas eval :

## ~/myprompt.sh

# 'ZSH_VERSION' est uniquement défini sous Zsh
# 'precmd' est un nom de fonction spécial connu de Zsh

[ ${ZSH_VERSION} ] && precmd() { myprompt; }

# 'BASH_VERSION' est uniquement défini sous Bash
# 'PROMPT_COMMAND' est un nom de variable d'environnement spécial connu de Bash

[ ${BASH_VERSION} ] && PROMPT_COMMAND=myprompt

# fonction appelée à chaque fois que l'interpréteur de commande est sur le point d'afficher l'invite
myprompt() {
  if [ ${ZSH_VERSION} ]; then
    # Syntaxe d'expansion de l'invite Zsh
    PS1='%{%F{red}%}%n%{%f%}@%{%F{red}%}%m %{%F{cyan}%}%~ %{%F{white}%}%# %{%f%}'
  elif [ ${BASH_VERSION} ]; then
    # Syntaxe d'expansion de l'invite Bash
    PS1='\[\e[31m\]\u\[\e[0m\]@\[\e[31m\]\h \[\e[36m\]\w \[\e[37m\]\$ \[\e[0m\]'
  fi
}

À exécuter à partir des scripts d'initialisation de l'interpréteur de commande :

## ~/.bashrc
. ~/myprompt.sh

et :

## ~/.zshrc
. ~/myprompt.sh

Les invites présentées ici ne sont que des exemples. On peut certainement faire des choses beaucoup plus complexes.

Pour plus de détails sur la configuration des fonctions d'invite, consultez : http://zsh.sourceforge.net/Doc/Release/Functions.html#index-precmd et http://www.gnu.org/software/bash/manual/bashref.html#Printing-a-Prompt.

Pour plus de détails sur les expansions de l'invite, consultez http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html et http://www.gnu.org/software/bash/manual/bashref.html#Printing-a-Prompt.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X