zsh fournit de belles fonctions de hook , y compris chpwd
pour exécuter une fonction après que l'utilisateur a changé de répertoire.
# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd # hi
J'essaie d'imiter ça en bash.
Contraintes:
- Il doit fonctionner à la fois dans des shells interactifs et non interactifs, ce qui signifie, je pense, qu'il ne peut pas s'appuyer sur quelque chose comme
$PROMPT_COMMAND
- Il ne peut pas être redéfini
cd
, car je veux qu'il fonctionne pour toute commande qui modifie les répertoires (par exemple,pushd
etpopd
) - Il doit s'exécuter après la commande de l'utilisateur, donc
trap "my_function" DEBUG
cela ne fonctionne pas, à moins que je ne puisse dire en quelque sorte, "exécutez d'abord le$BASH_COMMAND
nous avons piégé, puis faites aussi cela ..." Je vois que je peux éviter l'exécution automatique de$BASH_COMMAND
siextdebug
est activé et la fonction trap renvoie 1, mais je ne pense pas que je veux forcerextdebug
, et le retour1
pour une commande réussie (mais modifiée) semble incorrect.
La dernière partie - "exécuter après la commande de l'utilisateur" - est ce qui me dérange actuellement. Si je peux exécuter une fonction après chaque commande, je peux la faire vérifier si le répertoire a changé depuis notre dernière vérification. Par exemple:
function check_pwd() {
# true in a new shell (empty var) or after cd
if [ "$LAST_CHECKED_DIR" != "$PWD" ]; then
my_function
fi
LAST_CHECKED_DIR=$PWD
}
Suis-je sur la bonne voie ou existe-t-il une meilleure solution? Comment puis-je exécuter une commande dans bash après que l'utilisateur a changé de répertoire?
cd
,pushd
etpopd
? Combien d'autres façons de changer de répertoire?cd
comme principe.MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )
veuillez ne pas modifier les commandes Unix fiables.bash
ce qui fonctionne à peu près de la même manière sur tous les systèmes d'exploitation sur lesquels il fonctionne.Réponses:
Il n'y a aucun moyen qui réponde à ces contraintes
Il semble qu'il n'y ait aucun moyen de résoudre ce problème en bash avec mes contraintes. En général, les solutions possibles sont:
cd
,pushd
etpopd
, de sorte que toute commande qui change les répertoires d' abord exécuter la fonction crochet. Mais cela peut créer des problèmes car 1) la substitution doit être prudente pour terminer la tabulation comme la commande d'origine et retourner le même code de sortie et 2) si plusieurs outils adoptent cette approche, ils ne peuvent pas bien jouer ensembletrap 'my_function
DEBUGso that every command will run the hook function. This is suboptimal because 1) it runs before every command, 2) it runs *before*
cd`, pas après 3) il ne peut y avoir qu'une seule fonction de débogage, donc si un autre outil utilise cette approche, ils ne peuvent pas bien jouer ensemble$PROMPT_COMMAND
pour exécuter la fonction de crochet en premier. Ce n'est pas optimal car cela ne fonctionnera pas dans les shells non interactifs et parce que si un autre outil définit la commande d'invite, ils ne peuvent pas bien jouer ensemble.En bref, il semble que la seule excellente solution serait que bash fournisse quelque chose comme le
chpwd_functions
crochet de zshell , mais il semble impossible de le simuler correctement.la source
Si le responsable n'aime pas que vous changiez la définition de cd, une autre option serait de redéfinir toutes les commandes qui utilisent cet environnement dans le répertoire:
Cela serait assez efficace car le hook PWD et la configuration dans le répertoire ne seraient traités qu'en cas de besoin.
Dans votre exemple de fonction check_pwd, je pourrais changer:
à:
afin de passer dans le nouveau cwd (pourrait être plus modulaire, testable).
la source
Installez les outils inotify en fonction de votre distribution.
inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; done
Dans mon exemple, la commande suivante redémarrera
httpd
si quelque chose change (Modifier, Créer, Supprimer) dans le répertoire spécifié.la source