Preserve el historial de bash en múltiples ventanas de terminal


525

Constantemente tengo más de una terminal abierta. En cualquier lugar de dos a diez, haciendo varios bits y bobs. Ahora digamos que reinicio y abro otro conjunto de terminales. Algunos recuerdan ciertas cosas, algunos olvidan.

Quiero una historia que:

  • Recuerda todo desde cada terminal
  • Es accesible instantáneamente desde cada terminal (por ejemplo, si estoy lsen una, cambie a otra terminal que ya esté funcionando y luego presione hacia arriba, lsaparece)
  • No olvida el comando si hay espacios al frente del comando.

¿Algo que pueda hacer para que bash funcione más así?


57
Puedo ver la ventaja de eso, pero personalmente odiaría eso en mi caparazón. Por lo general, mantengo 3 o 4 pestañas abiertas en mi terminal para usos muy específicos: una para ejecutar 'make', una con vi, otra para ejecutar cosas, etc. Entonces, cuando compilo, voy a la pestaña 1, presiono y 'make 'aparece, y así sucesivamente. Esto es extremadamente productivo para mí. Entonces, si de repente voy a mi pestaña 'hacer' y golpeo y aparece un comando grep aleatorio, ¡me enojaría mucho! Sin embargo
axel_c

44
@axel_c eso es bastante cierto. No puedo pensar en una forma inteligente de hacerlo donde los terminales existentes solo ven su propia historia, pero los nuevos ven una lista cronológicamente precisa de comandos.
Oli

8
@Oli escribió: "No puedo pensar en una forma inteligente de hacerlo donde los terminales existentes solo ven su propia historia, pero los nuevos ven una lista cronológicamente precisa de comandos". ¿Qué tal (no probado): export PROMPT_COMMAND="history -a; $PROMPT_COMMAND". Los shells existentes agregarán cada comando al archivo de historial para ver nuevos shells, pero solo mostrarán sus propios historiales.
Chris Page

2
¿Desea que todo el historial se almacene por separado o todos se fusionen en un solo archivo de historial?
kbyrd el

3
La respuesta corta es: no está diseñada por los desarrolladores de bash. Las soluciones basadas en el enjuague y luego volver a leer la historia probablemente funcionen, pero tenga cuidado con Shlemiel The Painter . En palabras simples: la cantidad de trabajo de procesamiento entre cada comando es proporcional al tamaño del historial.
Stéphane Gourichon

Respuestas:


328

Agregue lo siguiente a ~ / .bashrc

# Avoid duplicates
export HISTCONTROL=ignoredups:erasedups  
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend

# After each command, append to the history file and reread it
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

20
El problema con esta solución PROMPT_COMMAND es que los números para cada elemento del historial cambian después de cada comando :(. Por ejemplo, si escribe history y 1) ls 2) rm, entonces lo hace! 1 para repetir 1, el número de historial puede cambiar y podría ejecutar el comando rm ...
Chris Kimpton

2
Cuando hago esto, otros terminales ya abiertos no tienen el último comando ingresado cuando presiono 'Arriba' hasta después de emitir un comando en ese terminal, ¿se espera esto? Si es así, ¿hay alguna forma de modificar verdaderamente el historial de otros terminales al instante?
Suan

77
@Suan, esto me parece correcto según los comandos. Descubrí que podemos emitir un comando nulo (solo presione la tecla Intro) para que el historial se actualice.
sabio

3
En realidad history -a(...) no desencadena el borrado de duplicados de acuerdo con esta respuesta a la pregunta Historial de Bash: "ignorar" y "borrar" configurando conflictos con el historial común en las sesiones . Esta respuesta también proporciona la secuencia de history -<option>comandos que funciona con la HISTCONTROL=ignoredups:erasedupsconfiguración.
Piotr Dobrogost

23
No hay razón para exportlas variables HISTCONTROLy PROMPT_COMMAND: las está definiendo .bashrcpara que se definan en cada shell (incluso en las no interactivas, lo que también es un desperdicio).
dolmen

248

Entonces, esto es todo lo relacionado con la historia .bashrc:

export HISTCONTROL=ignoredups:erasedups  # no duplicate entries
export HISTSIZE=100000                   # big big history
export HISTFILESIZE=100000               # big big history
shopt -s histappend                      # append to history, don't overwrite it

# Save and reload the history after each command finishes
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Probado con bash 3.2.17 en Mac OS X 10.5, bash 4.1.7 en 10.6.


3
Hmm .. Esto mata la capacidad de usar $! 34, ya que los números de comando cambian cada solicitud. ¿Hay alguna solución alternativa @Davide @Schof @kch?

55
Usa esto para obtener una historia infinita: golpea la historia eterna . SIN EMBARGO, esto es complementario al código anterior, ya que no se volverá a cargar automáticamente.

77
FYI Ninguna de las soluciones mencionadas aquí puede resolver el siguiente problema. Tengo dos ventanas de shell A y B. En la ventana de shell A, ejecuto sleep 9999y (sin esperar a que termine el sueño) en la ventana de shell B, quiero poder ver sleep 9999en el historial de bash.
pts

1
@pts Yo también tenía como objetivo el comportamiento en vivo, pero luego me di cuenta de que es más conveniente tener historias específicas de terminales que faciliten el trabajo en diferentes cosas en diferentes terminales. Encontré que esto es muy útil: stackoverflow.com/questions/338285/#answer-7449399 En base a eso, me hice un alias llamado hrefque actualiza el historial de mi terminal actual al instante y limpia el archivo de historial en el proceso. Cada vez que abro una nueva terminal, esa limpieza / sincronización se ejecuta en mi archivo bashrc para que la nueva terminal tenga el último historial. Lo estoy usando junto conhistory -a
trusktr

66
No hay razón para exportlas variables: las está definiendo .bashrcpara que se definan en cada shell (incluso en las no interactivas, que también es un desperdicio)
dolmen

117

Aquí está mi intento de compartir el historial de sesiones de Bash. Esto permitirá compartir el historial entre sesiones bash de manera que el contador del historial no se mezcle y la expansión del historial !numberfuncione (con algunas restricciones).

Usando Bash versión 4.1.5 bajo Ubuntu 10.04 LTS (Lucid Lynx).

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

_bash_history_sync() {
    builtin history -a         #1
    HISTFILESIZE=$HISTSIZE     #2
    builtin history -c         #3
    builtin history -r         #4
}

history() {                  #5
    _bash_history_sync
    builtin history "$@"
}

PROMPT_COMMAND=_bash_history_sync

Explicación:

  1. Agregue la línea recién ingresada a $HISTFILE(el valor predeterminado es .bash_history). Esto hará $HISTFILEque crezca una línea.

  2. Al establecer la variable especial $HISTFILESIZEen algún valor, Bash se truncará $HISTFILEy no será más largo que las $HISTFILESIZElíneas al eliminar las entradas más antiguas.

  3. Borrar el historial de la sesión en ejecución. Esto reducirá el contador de historial en la cantidad de $HISTSIZE.

  4. Lea los contenidos $HISTFILEe insértelos en el historial actual de la sesión en ejecución. esto elevará el contador de historial por la cantidad de líneas en $HISTFILE. Tenga en cuenta que el recuento de líneas de $HISTFILEno es necesariamente $HISTFILESIZE.

  5. La history()función anula el historial incorporado para asegurarse de que el historial esté sincronizado antes de que se muestre. Esto es necesario para la expansión del historial por número (más sobre esto más adelante).

Más explicaciones:

  • El paso 1 asegura que el comando de la sesión actual se escriba en el archivo de historial global.

  • El paso 4 asegura que los comandos de las otras sesiones se lean en el historial de la sesión actual.

  • Debido a que el paso 4 elevará el contador de historial, necesitamos reducir el contador de alguna manera. Esto se hace en el paso 3.

  • En el paso 3, el contador de historial se reduce en $HISTSIZE. En el paso 4, el contador de historial se eleva por el número de líneas en $HISTFILE. En el paso 2 nos aseguramos de que el recuento de líneas $HISTFILEsea ​​exactamente $HISTSIZE(esto significa que $HISTFILESIZEdebe ser el mismo que $HISTSIZE).

Sobre las limitaciones de la expansión de la historia:

Cuando use la expansión del historial por número, siempre debe buscar el número inmediatamente antes de usarlo. Eso significa que no se mostrará un mensaje bash entre buscar el número y usarlo. Eso generalmente significa no enter y no ctrl + c.

Generalmente, una vez que tiene más de una sesión de Bash, no hay garantía alguna de que una expansión del historial por número retenga su valor entre dos pantallas de solicitud de Bash. Porque cuando PROMPT_COMMANDse ejecuta, el historial de todas las demás sesiones de Bash se integra en el historial de la sesión actual. Si cualquier otra sesión bash tiene un nuevo comando, los números del historial de la sesión actual serán diferentes.

Encuentro esta restricción razonable. De todos modos, tengo que buscar el número cada vez porque no puedo recordar números arbitrarios del historial.

Usualmente uso la expansión del historial por un número como este

$ history | grep something #note number
$ !number

Recomiendo usar las siguientes opciones de Bash.

## reedit a history substitution line if it failed
shopt -s histreedit
## edit a recalled history line before executing
shopt -s histverify

Errores extraños:

Ejecutar el comando de historial canalizado a cualquier cosa hará que ese comando aparezca en el historial dos veces. Por ejemplo:

$ history | head
$ history | tail
$ history | grep foo
$ history | true
$ history | false

Todos aparecerán en la historia dos veces. No tengo ni idea de porqué.

Ideas para mejoras:

  • Modifique la función _bash_history_sync()para que no se ejecute siempre. Por ejemplo, no debe ejecutarse después de a CTRL+Cen el indicador. A menudo uso CTRL+Cpara descartar una línea de comando larga cuando decido que no quiero ejecutar esa línea. A veces tengo que usar CTRL+Cpara detener un script de finalización de Bash.

  • Los comandos de la sesión actual siempre deben ser los más recientes en el historial de la sesión actual. Esto también tendrá el efecto secundario de que un número de historial dado mantiene su valor para las entradas de historial de esta sesión.


1
¿Por qué no "history -n" (líneas de recarga no cargadas) en lugar de "history -c; history -r"?
Graham

@Graham: No quería usarlo history -nporque arruina el contador de historial. Además, me pareció history -ndemasiado poco confiable.
lesmana

1
Una desventaja: los comandos con cadenas de varias líneas normalmente todavía se conservan en la sesión actual. Con este truco, se dividen en líneas individuales al instante. Usar -n para -c -r no ayuda, tampoco cmdhist o lithist. No creo que haya una solución en este momento.
Jo Liss

24
Después de intentar esto por un momento, en realidad descubrí que ejecutar solo history -a, sin -cy -r, es mejor en cuanto a usabilidad (aunque no es lo que se pregunta). Significa que los comandos que ejecuta están disponibles instantáneamente en nuevos shells incluso antes de salir del shell actual, pero no en shells que se ejecutan simultáneamente. De esta forma, Arrow-Up siempre selecciona los comandos de la última ejecución de la sesión actual , lo que encuentro mucho menos confuso.
Jo Liss

excepcionalmente buena respuesta, esto funciona de manera confiable a diferencia de la más común "historia -a; historia -n"
RichVel

42

No conozco ninguna forma de usar bash. Pero es una de las características más populares de zsh.
Personalmente prefiero zshmás de bashlo que recomiendo probarlo.

Aquí está la parte de mi .zshrcque trata con la historia:

SAVEHIST=10000 # Number of entries
HISTSIZE=10000
HISTFILE=~/.zsh/history # File
setopt APPEND_HISTORY # Don't erase history
setopt EXTENDED_HISTORY # Add additional data to history like timestamp
setopt INC_APPEND_HISTORY # Add immediately
setopt HIST_FIND_NO_DUPS # Don't show duplicates in search
setopt HIST_IGNORE_SPACE # Don't preserve spaces. You may want to turn it off
setopt NO_HIST_BEEP # Don't beep
setopt SHARE_HISTORY # Share history between session/terminals


16

Para hacer esto, necesitará agregar dos líneas a su ~/.bashrc:

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

De man bash:

Si la opción de shell histappend está habilitada (consulte la descripción de shopt en COMANDOS DE CONSTRUCCIÓN DE SHELL a continuación), las líneas se agregan al archivo de historial; de lo contrario, el archivo de historial se sobrescribe.


10

Puede editar su solicitud BASH para ejecutar el "historial -a" y el "historial -r" que sugirió Muerr:

savePS1=$PS1

(en caso de que arruines algo, lo cual está casi garantizado)

PS1=$savePS1`history -a;history -r`

(tenga en cuenta que estos son ticks de retroceso; ejecutarán el historial -a e history -r en cada solicitud. Dado que no generan ningún texto, su solicitud no se modificará.

Una vez que haya configurado su variable PS1 de la manera que desee, configúrela permanentemente en su archivo ~ / .bashrc.

Si desea volver a su mensaje original durante la prueba, haga lo siguiente:

PS1=$savePS1

He realizado pruebas básicas sobre esto para asegurarme de que funciona, pero no puedo hablar de ningún efecto secundario que se ejecute history -a;history -ren cada solicitud.


2
La solución de kch funciona mejor que la mía. Ahora estoy usando su solución en mi .bashrc.

9

Si necesita una solución de sincronización de historial bash o zsh que también resuelva el problema a continuación, puede verla en http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.html

El problema es el siguiente: tengo dos ventanas de shell A y B. En la ventana de shell A, ejecuto sleep 9999y (sin esperar a que termine el sueño) en la ventana de shell B, quiero poder ver sleep 9999en el historial de bash.

La razón por la cual la mayoría de las otras soluciones aquí no resolverán este problema es que están escribiendo sus cambios de historial en el archivo de historial utilizando , PROMPT_COMMANDo PS1ambos se ejecutan demasiado tarde, solo después de que el sleep 9999comando ha finalizado.


1
Esta es una buena solución, pero tengo algunas preguntas. 1. ¿Puedo usar el archivo .bash_history original? No quiero que exista otro archivo de historial de bash en mi $ HOME 2. Tal vez debas considerar establecer un repositorio github para esto.
weynhamz

Parece que el enlace de depuración está en conflicto con bashdb, el resultado siguiente cada vez que inicio una sesión de bash. `` bash debugger, bashdb, versión 4.2-0.8 Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Rocky Bernstein Este es un software gratuito, cubierto por la Licencia Pública General de GNU, y usted es bienvenido a cambiarlo y / o distribuir copias de él bajo ciertas condiciones. ** Error de depuración interna _Dbg_is_file (): argumento de archivo null bash: _Dbg_filenames [$ fullname]: subíndice de matriz incorrecto ``
weynhamz

@Techlive Zheng: 1. El .bash_history original no es compatible deliberadamente, porque .merged_bash_history utiliza un formato de archivo diferente, por lo que en caso de que .merged_bash_history no se cargue correctamente, bash no bloqueará accidentalmente el historial acumulado. Robustez por diseño, se mantendrá como está. 2. Un repositorio de github es una buena idea en general, pero no tengo tiempo para mantener eso para este proyecto, así que no lo estoy haciendo. - Sí, entra en conflicto con bashdb, y no hay una solución fácil (usan los mismos ganchos). No planeo trabajar en una solución, pero estoy aceptando parches.
pts

OK gracias. Se me ocurrió una sulotión mucho más simple y mejor.
weynhamz

@TechliveZheng: ¿Compartiría su solución simple y mejor con nosotros para que todos podamos aprender de ella? (Si es así, agregue una respuesta a la pregunta.)
pts

8

Puede usar history -apara agregar el historial de la sesión actual al archivo histórico, luego usarlo history -ren los otros terminales para leer el archivo histórico. 


8

Bien, finalmente esto me molestó al encontrar una solución decente:

# Write history after each command
_bash_history_append() {
    builtin history -a
}
PROMPT_COMMAND="_bash_history_append; $PROMPT_COMMAND"

Lo que esto hace es una especie de amalgama de lo que se dijo en este hilo, excepto que no entiendo por qué volverías a cargar la historia global después de cada comando. Muy rara vez me importa lo que sucede en otras terminales, pero siempre ejecuto una serie de comandos, por ejemplo, en una terminal:

make
ls -lh target/*.foo
scp target/artifact.foo vm:~/

(Ejemplo simplificado)

Y en otro:

pv ~/test.data | nc vm:5000 >> output
less output
mv output output.backup1

De ninguna manera me gustaría que se compartiera el comando


1
La razón por la que volvería a cargar el historial después de cada comando es porque es el comportamiento requerido por la pregunta (y, por lo tanto, esto realmente no responde la pregunta como se plantea).
Michael Homer

2
@MichaelHomer Punto justo. Siéntase libre de votar hacia abajo para que la respuesta permanezca en la parte inferior, sin embargo, lo atribuiría al OP sin darme cuenta de cuán malo sería el comportamiento solicitado, y el hecho de que esta es una pregunta muy fácil de buscar.
Yarek T

3
Op aquí, sí, eso es un compromiso justo. Mi queja principal es que estaba perdiendo historia. Esto debería detener eso, incluso si no significa actualizaciones instantáneas en sesiones simultáneas.
Oli

7

Aquí hay una alternativa que uso. Es engorroso pero aborda el problema que @axel_c mencionó en el que a veces es posible que desee tener una instancia de historial separada en cada terminal (una para hacer, una para monitorear, una para vim, etc.).

Mantengo un archivo de historial adjunto separado que actualizo constantemente. Tengo lo siguiente asignado a una tecla de acceso rápido:

history | grep -v history >> ~/master_history.txt

Esto agrega todo el historial desde el terminal actual a un archivo llamado master_history.txt en su directorio de inicio.

También tengo una tecla de acceso rápido separada para buscar en el archivo de historial maestro:

cat /home/toby/master_history.txt | grep -i

Yo uso gato | grep porque deja el cursor al final para ingresar mi expresión regular. Una forma menos fea de hacer esto sería agregar un par de secuencias de comandos a su ruta para realizar estas tareas, pero las teclas de acceso rápido funcionan para mis propósitos. También periódicamente extraeré el historial de otros hosts en los que he trabajado y agregaré ese historial a mi archivo master_history.txt.

Siempre es bueno poder buscar rápidamente y encontrar esa expresión regular difícil de usar que usaste o esa extraña frase de perl que se te ocurrió hace 7 meses.


6

Puedo ofrecer una solución para ese último: asegúrese de que la variable env HISTCONTROL no especifique "ignorespace" (o "ignoreboth").

Pero siento tu dolor con múltiples sesiones concurrentes. Simplemente no se maneja bien en bash.


6

Aquí está mi mejora a la respuesta de @lesmana . La principal diferencia es que las ventanas concurrentes no comparten el historial. Esto significa que puede seguir trabajando en sus ventanas, sin que el contexto de otras ventanas se cargue en sus ventanas actuales.

Si escribe explícitamente 'historial', O si abre una nueva ventana, obtiene el historial de todas las ventanas anteriores.

Además, utilizo esta estrategia para archivar todos los comandos escritos en mi máquina.

# Consistent and forever bash history
HISTSIZE=100000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
}

_bash_history_sync_and_reload() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

history() {                  #5
  _bash_history_sync_and_reload
  builtin history "$@"
}

export HISTTIMEFORMAT="%y/%m/%d %H:%M:%S   "
PROMPT_COMMAND='history 1 >> ${HOME}/.bash_eternal_history'
PROMPT_COMMAND=_bash_history_sync;$PROMPT_COMMAND

5

Elegí poner el historial en un archivo por tty, ya que varias personas pueden estar trabajando en el mismo servidor; la separación de los comandos de cada sesión facilita la auditoría.

# Convert /dev/nnn/X or /dev/nnnX to "nnnX"
HISTSUFFIX=`tty | sed 's/\///g;s/^dev//g'`
# History file is now .bash_history_pts0
HISTFILE=".bash_history_$HISTSUFFIX"
HISTTIMEFORMAT="%y-%m-%d %H:%M:%S "
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=5000

La historia ahora se ve así:

user@host:~# test 123
user@host:~# test 5451
user@host:~# history
1  15-08-11 10:09:58 test 123
2  15-08-11 10:10:00 test 5451
3  15-08-11 10:10:02 history

Con los archivos como:

user@host:~# ls -la .bash*
-rw------- 1 root root  4275 Aug 11 09:42 .bash_history_pts0
-rw------- 1 root root    75 Aug 11 09:49 .bash_history_pts1
-rw-r--r-- 1 root root  3120 Aug 11 10:09 .bashrc

3

Aquí señalaré un problema con

export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

y

PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"

Si ejecuta source ~ / .bashrc, $ PROMPT_COMMAND será como

"history -a; history -c; history -r history -a; history -c; history -r"

y

"history -a; history -n history -a; history -n"

Esta repetición ocurre cada vez que ejecuta 'source ~ / .bashrc'. Puede verificar PROMPT_COMMAND después de cada vez que ejecute 'source ~ / .bashrc' ejecutando 'echo $ PROMPT_COMMAND'.

Podría ver que algunos comandos aparentemente están rotos: "history -n history -a". Pero la buena noticia es que todavía funciona, porque otras partes todavía forman una secuencia de comandos válida (solo implica un costo adicional debido a la ejecución de algunos comandos de forma repetitiva. Y no tan limpio).

Personalmente uso la siguiente versión simple:

shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r"

que tiene la mayoría de las funcionalidades, mientras que no existe el problema mencionado anteriormente.

Otro punto a destacar es: realmente no hay nada mágico . PROMPT_COMMAND es solo una variable de entorno de bash simple. Los comandos en él se ejecutan antes de obtener bash prompt (el signo $). Por ejemplo, su PROMPT_COMMAND es "echo 123" y ejecuta "ls" en su terminal. El efecto es como ejecutar "ls; echo 123".

$ PROMPT_COMMAND="echo 123"

salida (como ejecutar 'PROMPT_COMMAND = "echo 123"; $ PROMPT_COMMAND'):

123

Ejecute lo siguiente:

$ echo 3

salida:

3
123

"history -a" se usa para escribir los comandos de historial en memoria en ~ / .bash_history

"history -c" se usa para borrar los comandos de historial en la memoria

"history -r" se usa para leer comandos de historial desde ~ / .bash_history a la memoria

Consulte la explicación del comando de historial aquí: http://ss64.com/bash/history.html

PD: Como han señalado otros usuarios, la exportación es innecesaria. Ver: uso de exportar en .bashrc


2

He escrito un script para configurar un archivo de historial por sesión o tarea que se basa en lo siguiente.

        # write existing history to the old file
        history -a

        # set new historyfile
        export HISTFILE="$1"
        export HISET=$1

        # touch the new file to make sure it exists
        touch $HISTFILE
        # load new history file
        history -r $HISTFILE

No es necesario guardar todos los comandos del historial, pero guarda los que me interesan y es más fácil recuperarlos que luego ejecutar cada comando. Mi versión también enumera todos los archivos del historial y ofrece la posibilidad de buscar en todos ellos.

Fuente completa: https://github.com/simotek/scripts-config/blob/master/hiset.sh


2

¡Aquí hay una solución que no mezcla historias de sesiones individuales!

Básicamente, uno tiene que almacenar el historial de cada sesión por separado y recrearlo en cada solicitud. Sí, utiliza más recursos, pero no es tan lento como puede parecer: el retraso comienza a ser notable solo si tiene más de 100000 entradas en el historial.

Aquí está la lógica central:

# on every prompt, save new history to dedicated file and recreate full history
# by reading all files, always keeping history from current session on top.
update_history () {
  history -a ${HISTFILE}.$$
  history -c
  history -r
  for f in `ls ${HISTFILE}.[0-9]* | grep -v "${HISTFILE}.$$\$"`; do
    history -r $f
  done
  history -r "${HISTFILE}.$$"
}
export PROMPT_COMMAND='update_history'

# merge session history into main history file on bash exit
merge_session_history () {
  cat ${HISTFILE}.$$ >> $HISTFILE
  rm ${HISTFILE}.$$
}
trap merge_session_history EXIT

Consulte este resumen para obtener una solución completa, que incluye algunas medidas de seguridad y optimizaciones de rendimiento.


1

Esto funciona para ZSH

##############################################################################
# History Configuration for ZSH
##############################################################################
HISTSIZE=10000               #How many lines of history to keep in memory
HISTFILE=~/.zsh_history     #Where to save history to disk
SAVEHIST=10000               #Number of history entries to save to disk
#HISTDUP=erase               #Erase duplicates in the history file
setopt    appendhistory     #Append history to the history file (no overwriting)
setopt    sharehistory      #Share history across terminals
setopt    incappendhistory  #Immediately append to the history file, not just when a term is killed

desafortunadamente la pregunta es estrictamente para bash :-)
Jaleks

1
es el primer resultado en Google cuando busco zsh también ... Pensé que podría ayudar
Mulki

3
Debería hacer una nueva pregunta, ~ "Conservar el historial de zsh en múltiples ventanas de terminal", suponiendo que ya no exista una. Está perfectamente bien, incluso animado, responder su propia pregunta si es una buena pregunta.
Oli

1

Hace tiempo que quería esto, especialmente la capacidad de recuperar un comando por donde se ejecutó para volver a ejecutarlo en un nuevo proyecto (o encontrar un directorio mediante un comando). Así que armé esta herramienta , que combina soluciones anteriores para almacenar un historial global de CLI con una herramienta interactiva de grepping llamada percol (asignada a C ^ R). Todavía está resbaladizo en la primera máquina que comencé a usar, ahora con un historial de CLI> 2 años.

No se mete con el historial de CLI local en lo que respecta a las teclas de flecha, pero le permite acceder al historial global con bastante facilidad (que también puede asignar a algo que no sea C ^ R)


esto es para zsh?
sjas

1
sí, lo hice para zsh inicialmente. Sin embargo, también funcionó para bash y fish. Avísame si funciona o no. No lo he cambiado en mucho tiempo y no estoy seguro de cuán claro he sido en mis instrucciones de instalación
Gordon Wells

1

Porque prefiero la historia infinita que guardé en un archivo personalizado. Creo esta configuración basada en https://stackoverflow.com/a/19533853/4632019 :

export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="[%F %T] "

export HISTFILE=~/.bash_myhistory
PROMPT_COMMAND="history -a; history -r; $PROMPT_COMMAND"

-1

Aquí está el fragmento de mi .bashrc y explicaciones cortas donde sea necesario:

# The following line ensures that history logs screen commands as well
shopt -s histappend

# This line makes the history file to be rewritten and reread at each bash prompt
PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"
# Have lots of history
HISTSIZE=100000         # remember the last 100000 commands
HISTFILESIZE=100000     # start truncating commands after 100000 lines
HISTCONTROL=ignoreboth  # ignoreboth is shorthand for ignorespace and     ignoredups

HISTFILESIZE y HISTSIZE son preferencias personales y puede cambiarlas según sus gustos.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.