GNU/Linux >> Tutoriales Linux >  >> Linux

Historial de BASH truncado a 500 líneas en cada inicio de sesión

El problema en realidad se reduce al diferente comportamiento de los shells de inicio de sesión y de no inicio de sesión. Había configurado las variables que controlan el historial en mi ~/.bahsrc . Este archivo no se lee cuando uno inicia un shell de inicio de sesión, solo lo leen los shells interactivos que no son de inicio de sesión (desde man bash ):

Cuando bash se invoca como un shell de inicio de sesión interactivo o como un shell no interactivo con el --login opción, primero lee y ejecuta comandos desde el archivo /etc/profile , si ese archivo existe. Después de leer ese archivo, busca ~/.bash_profile,~/.bash_login y ~/.profile , en ese orden, y lee y ejecuta comandos desde el primero que existe y es legible. El --noprofile La opción se puede usar cuando se inicia el shell para inhibir este comportamiento.

[. . . ]

Cuando se inicia un shell interactivo que no es un shell de inicio de sesión, bash lee y ejecuta comandos desde ~/.bashrc, si ese archivo existe. Esto se puede inhibir usando la opción --norc. La opción de archivo --rcfile obligará a bash a leer y ejecutar comandos desde el archivo en lugar de ~/.bashrc.

Por lo tanto, cada vez que inicié sesión, bajé a un tty o usé ssh, el .history el archivo se truncaba porque no lo había configurado en el tamaño correcto en ~/.profile también. Finalmente me di cuenta de esto y simplemente configuré las variables en ~/.profile donde pertenecen, en lugar de ~/.bashrc

Entonces, la razón por la que mi ~/.history se estaba truncando porque solo había configurado las variables HISTORIAL en un archivo leído por shells interactivos que no son de inicio de sesión y, por lo tanto, cada vez que ejecutaba un tipo diferente de shell, las variables se ignoraban y el archivo se cortaba en consecuencia.


Mi sugerencia es usar otro archivo como HISTFILE , no el predeterminado ~/.bash_history .

Aunque no tengo una explicación analítica, intentaré esbozar lo que me llevó a esta sugerencia:Si usa bash como su shell predeterminado (de inicio de sesión) y también use X (lo cual es muy probable) tiene un bash en ejecución instancia justo después del inicio de sesión (gráfico):

systemd
 ...
  |-login
  |   `-bash      <<====
  |       `-slim
  |           |-X -nolisten tcp vt07 -auth /var/run/slim.auth
  |           |  `-{X}
  |           `-fluxbox
  |               `-xterm -bg black -fg white
  |                   `-bash
 ...

Creo que esta instancia es un shell de inicio de sesión, por lo que no lee su ~/.bashrc y por lo tanto no sabrá nada sobre el histappend opción:

golpe de hombre(1) :Cuando un shell interactivo que no es un inicio de sesión Shell se inicia, bash lee y ejecuta comandos desde /etc/bash.bashrc y ~/.bashrc, si estos archivos existen. (...)

Mientras se ejecute este "shell principal", todo está bien, pero al finalizar (es decir, detener el sistema) anulará ~/.bash_history (porque ese es el valor predeterminado) y desordena su historial o lo recorta en el inicio del sistema a (de nuevo predeterminado) 500 líneas. (O tal vez ambos...)

También me llama la atención que no es suficiente incluir la configuración del historial en ~/.bashrc , ya que esto no debería ser una configuración tan poco común. No tengo explicación para eso.

Con respecto a su problema, que "los shells de inicio de sesión aún muestran el mismo comportamiento", puede intentar incluir la configuración del historial también en ~/.bash_profile :

golpe de hombre(1) :Cuando se invoca a bash como un shell de inicio de sesión interactivo, o como un shell no interactivo con la opción --login, primero lee y ejecuta comandos desde el archivo /etc/profile, si ese archivo existe. Después de leer ese archivo, busca ~/.bash_profile, (...)

Desafortunadamente, no puedo publicar una explicación más justificada con detalles de mi propio bash config, ya que soy un zsh tipo...


Dado que todas sus configuraciones están en orden de acuerdo con la página del manual, y dado que el archivo de historial no está restringido por tamaño (bytes), la única explicación posible que se me ocurre. Tiene que ver con cómo muere el caparazón.

De acuerdo con la referencia en línea, la salida ordenada (historial guardado) ocurre solo cuando el shell recibe SIGHUP. Realmente no puedo explicar cómo su sistema propaga señales cuando se reinicia, pero sospecho que su shell se cierra con SIGKILL o SIGPWR.

Podría deberse a que su WM se ejecuta de forma asíncrona (esperar) y el emulador de terminal generado desde el WM donde bash recibe una señal de salida forzada que no sea SIGHUP. También podría ser que el sistema operativo sea demasiado rápido para enviar la "eliminación final" a todos los procesos antes de que el SIGHUP elegante inicial logre llegar al shell a través de X -> WM -> xterm, posiblemente porque X o WM tardan más en salir que se necesita que el sistema operativo esté listo para caer.

Estoy en aguas profundas con estas cosas, pero creo que algo en ese sentido causa el comportamiento errático. He tenido este problema antes, y el remedio más sólido es exit en bash donde quieres guardar el historial.

Noté history -a en su pregunta, y no puedo pensar por qué eso no sería suficiente para preservar la historia.

Puede solucionar el problema averiguando qué es lo que realmente mata su bash y pasar a averiguar dónde se origina la señal y solucionar el problema allí, o simplemente vaciar el historial cuando sepa qué señal es la última (suponiendo que los discos todavía estén en línea para entonces). ):

trap "echo got 1  >/tmp/sig1;  exit" SIGHUP
trap "echo got 2  >/tmp/sig2;  exit" SIGINT
trap "echo got 15 >/tmp/sig15; exit" SIGTERM
 .. and so on...

La captura de pantalla incluida ilustra de lo que estoy hablando en el segundo y tercer párrafo. La secuencia allí es I shell en desde la izquierda , mata el caparazón izquierdo de la derecha y lee la historia.

golpe de hombre

Al iniciar, (...) El archivo nombrado por el valor de HISTFILE se trunca, si es necesario, para que no contenga más del número de líneas especificado por el valor de HISTFILESIZE (+ 500 por defecto).

Si la opción de shell histappend está habilitada (+ por defecto aquí), las líneas se agregan al archivo de historial; de lo contrario, se sobrescribe el archivo de historial.

referencia en línea

3.7.6 Señales

Cuando Bash es interactivo, en ausencia de trampas, ignora SIGTERM (para que 'matar 0' no elimine un shell interactivo), y SIGINT es capturado y manejado (para que la espera interna sea interrumpible). Cuando Bash recibe un SIGINT, sale de cualquier bucle en ejecución. En todos los casos, Bash ignora SIGQUIT. Si el control de trabajos está en vigor (consulte Control de trabajos), Bash ignora SIGTTIN, SIGTTOU y SIGTSTP.

Los comandos no incorporados iniciados por Bash tienen controladores de señal establecidos en los valores heredados por el shell de su padre. Cuando el control de trabajos no está en vigor, los comandos asincrónicos ignoran SIGINT y SIGQUIT además de estos controladores heredados. Los comandos que se ejecutan como resultado de la sustitución de comandos ignoran las señales de control de trabajo generadas por teclado SIGTTIN, SIGTTOU y SIGTSTP.

El shell sale de forma predeterminada al recibir un SIGHUP. Antes de salir, un shell interactivo vuelve a enviar el SIGHUP a todos los trabajos, en ejecución o detenidos. Los trabajos detenidos se envían SIGCONT para asegurarse de que reciben SIGHUP. Para evitar que el shell envíe la señal SIGHUP a un trabajo en particular, debe eliminarse de la tabla de trabajos con la función de desposeimiento (consulte Funciones integradas de control de tareas) o marcarla para que no reciba SIGHUP usando disown -h.

Si la opción de shell huponexit se ha configurado con shopt (consulte The Shopt Builtin), Bash envía un SIGHUP a todos los trabajos cuando sale un shell de inicio de sesión interactivo.

Si Bash está esperando que se complete un comando y recibe una señal para la cual se ha establecido una trampa, la trampa no se ejecutará hasta que se complete el comando. Cuando Bash está esperando un comando asíncrono a través de la instrucción interna de espera, la recepción de una señal para la cual se ha configurado una trampa hará que la instrucción interna de espera regrese inmediatamente con un estado de salida mayor que 128, inmediatamente después de lo cual se ejecuta la trampa.

captura de pantalla demostrativa


Linux
  1. Personalización del shell Bash

  2. Analizando el historial de Bash en Linux

  3. Cómo verificar el historial de inicio de sesión de Linux

  4. Consejos de Unix Shell:Cambie el Shell de inicio de sesión de Bash a otros

  5. CentOS / RHEL:cómo deshabilitar el historial de shell BASH

Comando de historial en Linux (Bash History)

.bashrc frente a .bash_profile

¿Qué es Login Shell en Linux?

Uso de la función de historial en Bash Shell en el servidor Ubuntu 16.04 LTS

Ejecute el script bash después de iniciar sesión

Cómo:¿Historial ilimitado de Bash/shell?