zsh proporciona algunas buenas funciones de enlace , incluso chpwdpara ejecutar una función después de que el usuario cambie los directorios.
# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd # hi
Estoy tratando de emular eso en bash.
Restricciones:
- Debe funcionar tanto en shells interactivos como no interactivos, lo que creo que significa que no puede confiar en algo como
$PROMPT_COMMAND - No se puede redefinir
cd, porque quiero que funcione para cualquier comando que cambie los directorios (por ejemplo,pushdypopd) - Debe ejecutarse después del comando del usuario, por lo
trap "my_function" DEBUGque no funciona, a menos que pueda decir de alguna manera, "primero ejecute lo$BASH_COMMANDque atrapamos, luego también haga esto ..." Veo que puedo evitar la ejecución automática de$BASH_COMMANDif siextdebugestá habilitado y la función trap devuelve 1, pero no creo que quiera forzarextdebug, y regresar1para un comando exitoso (pero modificado) parece incorrecto.
La última parte, "ejecutar después del comando del usuario", es lo que actualmente me tiene perplejo. Si puedo ejecutar una función después de cada comando, puedo hacer que verifique si el directorio ha cambiado desde la última vez que lo verificamos. P.ej:
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
}
¿Estoy en el camino correcto, o hay una mejor manera? ¿Cómo puedo ejecutar un comando en bash después de que el usuario cambie los directorios?

cd,pushdypopd? ¿De cuántas otras maneras hay para cambiar el directorio?cdcomo principio.MYBIN=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )No modifique los comandos de confianza de Unix.bash, lo que funciona más o menos igual en todos los sistemas operativos en los que se ejecuta.Respuestas:
No hay forma de cumplir con estas limitaciones
Parece que no hay forma de resolver este problema en bash con mis restricciones. En general, las posibles soluciones son:
cd,pushdypopd, de manera que cualquier comando que cambia directorios primero se ejecutará la función de enlace. Pero esto puede crear problemas porque 1) la anulación debe tener cuidado al completar la pestaña como el comando original y devolver el mismo código de salida y 2) si más de una herramienta adopta este enfoque, no pueden jugar bien juntostrap 'my_functionDEBUGso that every command will run the hook function. This is suboptimal because 1) it runs before every command, 2) it runs *before*cd`, no después de 3) solo puede haber una función de depuración, por lo que si otra herramienta usa este enfoque, no pueden jugar bien juntos$PROMPT_COMMANDpara ejecutar la función de enlace primero. Esto es subóptimo porque no funcionará en shells no interactivos y porque si otra herramienta define el comando de solicitud, no pueden jugar bien juntos.En resumen, parece que la única gran solución sería si bash proporcionara algo como el
chpwd_functionsgancho de zshell , pero parece imposible simularlo correctamente.fuente
Si al mantenedor no le gusta que cambies la definición de cd, otra opción sería redefinir todos los comandos que usan este entorno en el directorio:
Esto sería bastante eficiente porque el enganche PWD y la configuración en el directorio solo se procesarían cuando sea necesario.
En su función check_pwd de ejemplo, podría cambiar:
a:
para pasar el nuevo cwd (podría ser más modular, comprobable).
fuente
Instale herramientas inotify de acuerdo con su distribución.
inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; doneEn mi ejemplo, el siguiente comando se reiniciará
httpdsi algo cambia (Modificar, Crear, Eliminar) en el directorio especificado.fuente