¿Cuál es la mejor manera de eliminar automáticamente .zsh_history después de un tiempo determinado?

¿Cuál es la mejor manera de eliminar automáticamente .zsh_history después de un tiempo determinado?

siento que haysin opción de configuración ZSHpara eliminar automáticamente .zsh_historydespué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_HISTORYformato (que incluye la hora de inicio de cada comando) y EXTENDED_HISTORYes 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 que echo *(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 bashsolo 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_historysobrescribir el archivo original, pero no asumo ninguna responsabilidad por la corrupción del archivo que pueda ocurrir.

Las entradas anteriores CUTOFFse eliminan (he usado 7 días en el ejemplo, pero puedes cambiar fácilmente 7a 30o 31durante un mes). Se supone que esto se ejecuta $HOMEcomo 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])

información relacionada