Comportamiento extraño del historial de bash al ejecutar varias sesiones

15

¿Cómo se almacena el historial de la línea de comandos cuando uso múltiples ventanas de terminal? Sé que está almacenado, .bash_historypero no puedo ver la lógica de qué historial se usa si abro una nueva ventana. Casi se siente no determinista en el sentido de que nunca sé qué comando veré si intento usar la flecha hacia arriba en una nueva ventana.

¿Alguien puede explicar esto?

¿Hay alguna manera de controlar el historial de tal manera que pueda reutilizar el historial desde una ventana en particular?

Alex Gitelman
fuente

Respuestas:

14

Para comprender el comportamiento del historial de bash primero debe saber lo siguiente:

  1. Existe el historial en el archivo de historial.
  2. Existe la historia en la memoria de un proceso bash.
  3. El historial en la memoria de un proceso bash no se sincroniza con el historial en la memoria de ningún otro proceso bash.
  4. El historial en la memoria de un proceso bash no se sincroniza con el historial en el archivo, a menos que se solicite explícitamente o durante algún evento específico (ver más abajo).

Usando la configuración predeterminada, el ciclo de vida de una sesión bash con respecto al historial es el siguiente:

  1. Durante el inicio, bash leerá el archivo de historial. El contenido del archivo de historial está ahora en la memoria del proceso bash.
  2. Durante el uso normal solo se manipula el historial en la memoria.
  3. Durante el apagado, el historial en la memoria se escribe en el archivo histórico, sobrescribiendo cualquier contenido anterior del archivo histórico.

El comportamiento aparentemente no determinista que ha observado se debe principalmente a que el contenido del archivo de historial es siempre el historial de la última sesión de bash cerrada, y bash solo lee el archivo de historial durante el inicio.

Lea el manual de bash para obtener una explicación más detallada del proceso de inicio y apagado.

Tenga en cuenta que con la configuración predeterminada me refiero a la configuración predeterminada de bash. Su distribución podría haber proporcionado un .bashrc(o /etc/bash.bashrc) que cambie este comportamiento.

Al habilitar la opción de shell histappend, puede indicarle a bash que agregue en lugar de sobrescribir el archivo de historial. Puede habilitar el histappenduso del comando shopt -s histappend. Para tener esta opción siempre habilitada, debe poner el comando en su .bashrc(u otro archivo de inicialización). Lea más sobre el shoptcomando en el manual de bash

Tenga en cuenta que la habilitación histappendno reducirá mucho el comportamiento aparentemente no determinista. Esto se debe a que cada sesión de bash todavía tiene su propio historial en la memoria. Es posible tener un historial bash mayormente sincronizado. Hay una guía sobre cómo hacer que cada proceso bash tenga un historial mayormente sincronizado en un hilo en el desbordamiento de la pila .

usando el comando incorporado historypuede decirle explícitamente a bash que lea el historial de un archivo a la memoria, o que escriba de memoria a archivo. Por ejemplo: history -rleerá el contenido del archivo y lo agregará al historial en la memoria. history -wescribirá el historial actual de la memoria al archivo, sobrescribiendo el contenido anterior. Esto es básicamente lo que sucede durante el apagado. Lea más sobre el historycomando en el manual de bash

Para completar, aquí hay una lista de las variables internas que modifican el comportamiento del historial:

  • HISTFILE: el archivo para leer y escribir el historial.
  • HISTFILESIZE: el recuento máximo de líneas para el archivo de historial.
  • HISTSIZE: el recuento máximo de líneas para el historial en la memoria.
  • HISTCONTROL, HISTIGNORE, HISTTIMEFORMAT: No es relevante para esta discusión. Lea el manual de bash para más detalles.
lesmana
fuente
Buena explicación. Usted mencionó el cierre, pero ¿qué pasa con matar la sesión terminal? La sesión puede cancelarse mediante el cierre de sesión o la interfaz de usuario o por otros medios, como la caída de la conexión de red. Si se reemplaza el archivo de historial completo y tiene varias sesiones, ¿está diciendo que el historial del último cerrado se usará en el archivo de historial? Eso podría explicar el comportamiento no determinista.
Alex Gitelman
el punto del ciclo de vida (3) no es correcto. Parece que solo la primera sesión de bash alguna vez escribirá en el archivo de historial. Prueba: Abra 2 sesiones en orden: a, b. Hacer 'echo hola' en b . Luego salga en b . Luego abra una nueva sesión c . Esta sesión no tendrá eco hola en su historia.
user606723
@AlexGitelman: si se mata un proceso bash, entonces no tendrá la posibilidad de sobrescribir el archivo de historial. y sí, el historial de la última sesión cerrada es el que estará en el archivo de historial.
lesmana
@ user606723: el punto 3 es correcto. lea el manual de bash. Experimente nuevamente utilizando un .bashrcarchivo mínimo . tenga en cuenta que su distribución podría haber cambiado algunas configuraciones en /etc/bash.bashrc. verifique específicamente la opción de shell histappend.
lesmana
0

AFAIK, los comandos bash se guardan después de que finaliza la sesión SSH. Por lo tanto, los comandos no se guardan cuando una sesión finaliza de manera anormal (por ejemplo, debido a una falla de la red). Estoy hablando aquí sobre sesiones SSH. Las terminales locales pueden usar un enfoque similar.

Al abrir varias sesiones al mismo tiempo, los comandos escritos en una sesión no se ven en la otra mientras ambos están activos. Sin embargo, verá estos comandos cuando finalice su sesión y vuelva a abrirlo.

Khaled
fuente
Este no es el comportamiento que he experimentado. Puedo confirmar esto haciendo una prueba rápida donde abro una sesión ssh, hago un comando y hago una salida elegante. En este caso, tuve otra sesión ssh previamente activa. En esta sesión de bash preexistente, verifico .bash_history y no encuentro nada grabado. Creo que la primera sesión de bash en ejecución es la única que termina grabando en .bash_history.
user606723
Terminar su sesión no afectará las sesiones actualmente en ejecución, ¡pero afectará las nuevas sesiones!
Khaled
¿Qué sucede si no es SSH sino la ventana de terminal Gnome que cierro a través de la interfaz de usuario?
Alex Gitelman
Necesita ser verificado. Actualmente, no tengo acceso a un terminal Gnome.
Khaled
@Khaled, probado, no afecta a las nuevas sesiones. (He comprobado .bash_history antes de todos modos, que es donde se pone fiesta de la historia de comandos para nuevas sesiones, yo sabía que por lo wouldn; t trabajo, pero te humour'ed de todos modos.)
user606723