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
ls
en una, cambie a otra terminal que ya esté funcionando y luego presione hacia arriba,ls
aparece) - No olvida el comando si hay espacios al frente del comando.
¿Algo que pueda hacer para que bash funcione más así?
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.Respuestas:
Agregue lo siguiente a ~ / .bashrc
fuente
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 dehistory -<option>
comandos que funciona con laHISTCONTROL=ignoredups:erasedups
configuración.export
las variablesHISTCONTROL
yPROMPT_COMMAND
: las está definiendo.bashrc
para que se definan en cada shell (incluso en las no interactivas, lo que también es un desperdicio).Entonces, esto es todo lo relacionado con la historia
.bashrc
:Probado con bash 3.2.17 en Mac OS X 10.5, bash 4.1.7 en 10.6.
fuente
sleep 9999
y (sin esperar a que termine el sueño) en la ventana de shell B, quiero poder versleep 9999
en el historial de bash.href
que 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
export
las variables: las está definiendo.bashrc
para que se definan en cada shell (incluso en las no interactivas, que también es un desperdicio)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
!number
funcione (con algunas restricciones).Usando Bash versión 4.1.5 bajo Ubuntu 10.04 LTS (Lucid Lynx).
Explicación:
Agregue la línea recién ingresada a
$HISTFILE
(el valor predeterminado es.bash_history
). Esto hará$HISTFILE
que crezca una línea.Al establecer la variable especial
$HISTFILESIZE
en algún valor, Bash se truncará$HISTFILE
y no será más largo que las$HISTFILESIZE
líneas al eliminar las entradas más antiguas.Borrar el historial de la sesión en ejecución. Esto reducirá el contador de historial en la cantidad de
$HISTSIZE
.Lea los contenidos
$HISTFILE
e 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$HISTFILE
no es necesariamente$HISTFILESIZE
.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$HISTFILE
sea exactamente$HISTSIZE
(esto significa que$HISTFILESIZE
debe 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_COMMAND
se 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
Recomiendo usar las siguientes opciones de Bash.
Errores extraños:
Ejecutar el comando de historial canalizado a cualquier cosa hará que ese comando aparezca en el historial dos veces. Por ejemplo:
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 aCTRL+C
en el indicador. A menudo usoCTRL+C
para descartar una línea de comando larga cuando decido que no quiero ejecutar esa línea. A veces tengo que usarCTRL+C
para 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.
fuente
history -n
porque arruina el contador de historial. Además, me parecióhistory -n
demasiado poco confiable.history -a
, sin-c
y-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.No conozco ninguna forma de usar
bash
. Pero es una de las características más populares dezsh
.Personalmente prefiero
zsh
más debash
lo que recomiendo probarlo.Aquí está la parte de mi
.zshrc
que trata con la historia:fuente
Para hacer esto, necesitará agregar dos líneas a su
~/.bashrc
:De
man bash
:fuente
Puede editar su solicitud BASH para ejecutar el "historial -a" y el "historial -r" que sugirió Muerr:
(en caso de que arruines algo, lo cual está casi garantizado)
(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:
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 -r
en cada solicitud.fuente
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 9999
y (sin esperar a que termine el sueño) en la ventana de shell B, quiero poder versleep 9999
en 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_COMMAND
oPS1
ambos se ejecutan demasiado tarde, solo después de que elsleep 9999
comando ha finalizado.fuente
Puede usar
history -a
para agregar el historial de la sesión actual al archivo histórico, luego usarlohistory -r
en los otros terminales para leer el archivo histórico.fuente
Bien, finalmente esto me molestó al encontrar una solución decente:
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:
(Ejemplo simplificado)
Y en otro:
De ninguna manera me gustaría que se compartiera el comando
fuente
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:
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:
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.
fuente
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.
fuente
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.
fuente
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.
La historia ahora se ve así:
Con los archivos como:
fuente
Aquí señalaré un problema con
y
Si ejecuta source ~ / .bashrc, $ PROMPT_COMMAND será como
y
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:
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".
salida (como ejecutar 'PROMPT_COMMAND = "echo 123"; $ PROMPT_COMMAND'):
Ejecute lo siguiente:
salida:
"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
fuente
He escrito un script para configurar un archivo de historial por sesión o tarea que se basa en lo siguiente.
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
fuente
¡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:
Consulte este resumen para obtener una solución completa, que incluye algunas medidas de seguridad y optimizaciones de rendimiento.
fuente
Esto funciona para ZSH
fuente
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)
fuente
Porque prefiero la historia infinita que guardé en un archivo personalizado. Creo esta configuración basada en https://stackoverflow.com/a/19533853/4632019 :
fuente
Aquí está el fragmento de mi .bashrc y explicaciones cortas donde sea necesario:
HISTFILESIZE y HISTSIZE son preferencias personales y puede cambiarlas según sus gustos.
fuente