¿Es posible hacer que escribir en .bash_history sea inmediato?

125

Yo muchas veces abiertos y mucha terminales [En este momento tengo 7 abierta en este espacio de trabajo] y yo busco a menudo historycon grepencontrar un comando que he escrito recientemente, pero no quiero dar caza a la terminal y luego desplazarse hacia arriba y buscarlo más, etc. A veces mis terminales se cierran sin 'salir', y todo lo que he escrito se pierde [A veces he necesitado algo que había escrito en un terminal que fue asesinado].

Entonces, ¿hay alguna manera de hacerlo para que cada terminal escriba en .bash_history inmediatamente? o al menos una vez por minuto, o algo así?

Mate
fuente
2
Normalmente lo uso control-rpara realizar búsquedas inversas en el historial de comandos de un bash. Más conveniente que a history | grepmenos que necesite una expresión regular.
Peter Cordes

Respuestas:

93

Una solución simple como se detalla en Actualizar el historial de Bash en tiempo real .

Dice poner esos comandos en la configuración .bashrc:

shopt -s histappend
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

El primer comando cambia el .historymodo de archivo para agregar. Y el segundo configura el history -acomando para ejecutarse en cada indicador de shell. El -aescribe inmediatamente las actuales nuevas líneas / en el archivo histórico.

Relacionado con zsh:

mario
fuente
1
bueno este tipo de trabajos Intenté algunas pruebas más y parece que solo funciona en el primer comando. ¿funciona correctamente para ti?
Matt
55

Intenta poner esto en tu .bashrc:

shopt -s histappend                      # append to history, don't overwrite it
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Crédito aquí: https://stackoverflow.com/questions/103944/real-time-history-export-amongst-bash-terminal-windows/3055135

history -cborra el historial de la sesión en ejecución. Esto reducirá el contador de historial en la cantidad de $HISTSIZE. history -rlea el contenido $HISTFILEe insértelos en el historial actual de la sesión en ejecución. Esto aumentará el contador del historial por la cantidad de líneas $HISTFILE.

Creo que significa que los comandos están disponibles casi de inmediato (tiene un terminal, escritura echo 1, segundo terminal echo 2, primero echo 3y al presionar la flecha hacia abajo dos veces, debería tener echo 2disponible. Debe emitir un comando en un terminal determinado para tener acceso a lo que tiene ha sido escrito

cenar
fuente
¡Brillante! Gracias. Preguntarse por qué esas opciones no están documentadas en man history...
artfulrobot
10
@artfulrobot: este comando está bashincorporado, por lo que se describe en man bash. También puedes usar help history.
pabouk
2
Tengo mi zsh configurado para funcionar de esta manera: cada shell rastrea su PROPIO historial (y antes de eso, el historial combinado), y cada comando se agrega al historial combinado. Esto es diferente y mejor que siempre volver a cargar el historial para cada comando para cada shell, porque tiendo a tener un "hilo de trabajo" o "trabajo" diferente para cada terminal de shell. Creo que esa es la diferencia entre esto con -ry -cvs simplemente tener -a.
Steven Lu
Entonces, ¿qué estás usando exactamente? history -c; history -r? Supongo que es mejor para ti, sería mejor para mí solo a veces, a menudo uso varios proyectiles para hacer un trabajo, así que prefiero tener el historial lo más combinado posible. De hecho, me importa que el comando se escriba en la historia solo después de que termine. normalmente, cuando inicio una sesión ssh en un host y quiero abrir otra mientras la primera aún se está ejecutando, tengo que volver a escribirla porque aún no se ha escrito en el historial.
sup
Creo que nunca me quedé el tiempo suficiente para descubrir cómo hacer que bash rastree simultáneamente hilos paralelos de la historia (por instancia de shell) mientras escribía inmediatamente la historia en el archivo de historia principal. Zsh hace que sea mucho más fácil hacerlo, además, además, he definido una función zsh para escribir muchos metadatos sofisticados en un archivo de historial mejorado de mi diseño. Se ha vuelto bastante indispensable. De todos modos, el mecanismo allí es precmd () y preexec () para zsh get args que describen el comando ingresado. Entonces se vuelve trivial dirigir eso a los archivos. history -apodría ser suficiente
Steven Lu
38

Tengo un archivo de historial grande con aproximadamente 100000 entradas, y las variantes que borran la lista de historial y leen todo el archivo de historial (usando history -cy history -r) introducen un retraso notable (quizás 0.2 segundos) antes de que se muestre el mensaje. El uso history -npara que solo se lean nuevas líneas del archivo de historial es más rápido:

shopt -s histappend
PROMPT_COMMAND='history -a;history -n'

PROMPT_COMMAND no tiene que exportarse porque es una variable de shell.

nisetama
fuente
¡Brillante! ¡No más historia perdida cuando se corta la conexión!
Tobia
Esto es maravilloso. Al agregar al archivo y leer el archivo, compartirá el historial en múltiples terminales.
wisbucky
3

Una nota para todas las demás respuestas (que son básicamente lo mismo):

Establecer PROMPT_COMMAND="history -a;$PROMPT_COMMAND"en el .bashrc(o amigos) es suficiente.

Además, puede ejecutar manualmente history -acada vez que quiera "capturar" el historial en la sesión actual.

El comando shopt -s histappendno es necesario porque history -asiempre agrega nuevas líneas al archivo y nunca lo sobrescribe. Además, al menos a partir de Bash 4, histappendes el comportamiento predeterminado.

Guss
fuente
En mi mac 10.13.6 parecía que no funcionaba sin el shopt -s histappend. También tenga en cuenta que lo agregué a mi~/.bash_profile
ubershmekel
Probablemente hay otra configuración en algún lugar de su sistema que se deshabilitó histappend, ya que ese es el comportamiento predeterminado. Lo buscaría, pero no tengo acceso a una Mac.
Guss