siento que haysin opción de configuración ZSHpara eliminar automáticamente .zsh_history
después de un cierto tiempo (por ejemplo, más de un mes a partir de ahora). ¿Cuál sería el truco más sencillo para lograrlo?
Respuesta1
Correcto, no hay opciones de vencimiento basadas en el tiempo para .zsh_history
. Probablemente porque cualquier tipo de vencimiento programado requiere el EXTENDED_HISTORY
formato (que incluye la hora de inicio de cada comando) y EXTENDED_HISTORY
es una característica nueva (más nueva), al menos más nueva que la mayoría de las opciones de vencimiento.
Además, la funcionalidad zsh no tiene la mejor relación con el concepto difuso de "tiempo"; simplemente lea las restricciones de las banderas globales basadas en el tiempo para apreciarlo:
Cualquier parte fraccionaria de la diferencia entre el tiempo de acceso y la parte actual en las unidades apropiadas se ignora en la comparación. Por ejemplo,
echo *(ah-5)
haría eco de los archivos a los que se accedió en las últimas cinco horas, mientras queecho *(ah+5)
haría eco de los archivos a los que se accedió hace al menos seis horas, ya que los tiempos estrictamente entre cinco y seis horas se tratan como cinco horas.
Más allá de eso, si tiene activada alguna de las opciones de eliminación de duplicados, zsh eliminarámás viejoentradas a favor de la más nueva, por lo que la lista de entradas "antiguas" está en constante cambio, lo que hace que el vencimiento basado en el tiempo sea más complicado.
Si desea hacerlo, como dice LSerni, analizarlo usted mismo probablemente sea la mejor opción. Una cosa complicada de hacer esto es que las entradas de varias líneas en el historial se escriben palabra por palabra, es decir, en varias líneas, por lo que no se puede analizar simplemente "línea por línea" porque algunas líneas no son entradas del historial, sino Son continuaciones.
Mi otra preocupación es que probablemente no hayarealmenteforma segura de hacer esto, excepto integrarlo directamente con la gestión del historial de zsh, porque cualquier código externo que modifique el archivo histórico está en constante peligro de sufrir interferencias (o interferir con) una instancia en ejecución de zsh
. Quiero decir, a menos que escribieras algo que bash
solo se ejecute cuandono es posibleiniciar sesión, como durante las partes de usuario único de los procesos de inicio o apagado.
Este código Python evita ese problema al copiar el historial en un archivo nuevo, leerlo y luego escribir las entradas que pasan la fecha límite a undiferentearchivo nuevo. El archivo de destino podría cambiarse para .zsh_history
sobrescribir el archivo original, pero no asumo ninguna responsabilidad por la corrupción del archivo que pueda ocurrir.
Las entradas anteriores CUTOFF
se eliminan (he usado 7 días en el ejemplo, pero puedes cambiar fácilmente 7
a 30
o 31
durante un mes). Se supone que esto se ejecuta $HOME
como directorio de trabajo.
Esto también supone que el historial está ordenado por tiempo, no sé qué tan segura sea esa suposición. (Si no es cierto, puede terminar conservando más entradas de las previstas, porque una vez que llega a la primera entrada con marca de tiempodespuésla hora límite, todo lo posterior está incluido. Por lo tanto, las entradas más antiguas que vienen después de la primera más nueva se conservarán accidentalmente. Lo que parece ser el tipo correcto de resultado incorrecto que se debe favorecer, en lugar de descartar cualquier cosa no deseada).
#!/usr/bin/python3
import shutil
import time
from itertools import dropwhile
CUTOFF = time.time() - (86400 * 7) # one week ago
hist = []
shutil.copy2(".zsh_history", ".zsh_history.bak")
with open(".zsh_history.bak", "rb") as f:
for l in f.readlines():
if l.startswith(b': '):
# Start of a new history entry
# Add a new tuple (time, history_line) to the list
ts = int(l.split(b':')[1])
hist.append((ts, l))
continue
# Continuation line, append it to the previous entry
prev = hist.pop()
hist.append((prev[0], b''.join([prev[1], l])))
with open(".zsh_history.new", "wb") as f:
# Drop list entries while timestamp < CUTOFF,
# Then write contents of each remaining entry to file
for l in dropwhile(lambda x: x[0] < CUTOFF, hist):
f.write(l[1])