GNU/Linux >> Tutoriales Linux >  >> Linux

¿Actualizar el historial de Bash en otras terminales al salir de una terminal?

Sé que esta pregunta no es oscura, ya que se hace aquí para seguir actualizándose (y duplicada aquí).

Lo que estoy tratando de lograr es un poco diferente. No me gusta la idea de que mi aviso reescriba un archivo cada ls Escribo (history -a; history -c; history -r ).

Me gustaría actualizar el archivo al salir. Eso es fácil (en realidad, predeterminado), pero debe agregar en lugar de volver a escribir:

shopt -s histappend

Ahora, cuando se cierra un terminal, me gustaría que todos los demás que quedan abiertos estén al tanto de la actualización.

Prefiero hacer esto sin verificar a través de $PS1 en cada command que escribo. Creo que sería mejor capturar algún tipo de señal. ¿Cómo lo harías tú? Si no es posible, tal vez un simple cronjob ?

¿Cómo podemos resolver este rompecabezas?

Respuesta aceptada:

¿Señales creativas y envolventes, dices? Bien:

trap on_exit EXIT
trap on_usr1 USR1

on_exit() {
    history -a
    trap '' USR1
    killall -u "$USER" -USR1 bash
}

on_usr1() {
    history -n
}

Tira eso en .bashrc y ve. Esto usa señales para decirle a cada bash proceso para verificar si hay nuevas entradas en el historial cuando sale otra. Esto es bastante horrible, pero realmente funciona.

¿Cómo funciona?

trap establece un controlador de señal para una señal del sistema o uno de los eventos internos de Bash. La EXIT evento es cualquier terminación controlada del shell, mientras que USR1 es SIGUSR1 , una señal sin sentido de que nos estamos apropiando.

Cada vez que sale el shell, nosotros:

  • Anexar todo el historial al archivo de forma explícita.
  • Deshabilitar el SIGUSR1 controlador y hacer que este shell ignore la señal.
  • Envía la señal a todos los bash en ejecución procesos del mismo usuario.

Cuando un SIGUSR1 llega, nosotros:

  • Cargue todas las entradas nuevas del archivo de historial en la lista de historial en memoria del shell.

Debido a la forma en que Bash maneja las señales, en realidad no obtendrá los nuevos datos del historial hasta que presione Enter la próxima vez, así que esto no funciona mejor en ese frente que poner history -n en PROMPT_COMMAND . Sin embargo, ahorra leer el archivo constantemente cuando no ha pasado nada, y no se escribe nada hasta que se cierra el shell.

Sin embargo, todavía hay un par de problemas aquí. La primera es que la respuesta predeterminada a SIGUSR1 es terminar el caparazón. Cualquier otro bash los procesos (ejecutando scripts de shell, por ejemplo) serán eliminados. .bashrc no se carga con shells no interactivos. En su lugar, un archivo nombrado por BASH_ENV está cargado:puede configurar esa variable en su entorno globalmente para que apunte a un archivo con:

trap '' USR1

en él para ignorar la señal en ellos (lo que resuelve el problema).

Relacionado:¿Comando de terminal para saber si un servidor es virtual o físico?

Finalmente, aunque esto hace lo que pediste, el orden que recibirás será un poco inusual. En particular, los fragmentos de la historia se repetirán en diferentes órdenes a medida que se cargan y guardan por separado. Eso es esencialmente inherente a lo que está solicitando, pero tenga en cuenta que el historial de flecha hacia arriba se vuelve mucho menos útil en este punto. Sin embargo, las sustituciones de historial y similares se compartirán y funcionarán bien.


Linux
  1. Analizando el historial de Bash en Linux

  2. ¿Por qué se produce un error en el aviso de Bash cuando examino el historial?

  3. Eliminar una determinada línea del archivo de historial de Bash

  4. ¿Cómo forzar el comando de terminal ls para mostrar resultados en Bytes mientras configuré el valor predeterminado en ls -h en el perfil de bash?

  5. ¿Cómo guardar + cerrar archivo al editar en bash?

Comando de historial en Linux (Bash History)

Bash:Agregar al archivo

Cómo hacer una copia de seguridad y restaurar el historial de la terminal de Linux

35 ejemplos de secuencias de comandos Bash

Cómo evitar entradas duplicadas en el historial de Bash en Linux

Localizadores de terminales