zsh proporciona algunas buenas funciones de enlace , incluso chpwd
para 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,pushd
ypopd
) - Debe ejecutarse después del comando del usuario, por lo
trap "my_function" DEBUG
que no funciona, a menos que pueda decir de alguna manera, "primero ejecute lo$BASH_COMMAND
que atrapamos, luego también haga esto ..." Veo que puedo evitar la ejecución automática de$BASH_COMMAND
if siextdebug
está habilitado y la función trap devuelve 1, pero no creo que quiera forzarextdebug
, y regresar1
para 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
,pushd
ypopd
? ¿De cuántas otras maneras hay para cambiar el directorio?cd
como 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
,pushd
ypopd
, 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_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`, 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_COMMAND
para 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_functions
gancho 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; done
En mi ejemplo, el siguiente comando se reiniciará
httpd
si algo cambia (Modificar, Crear, Eliminar) en el directorio especificado.fuente