bash guardar historial sin salir

16

en linux ubuntu bash terminal. ¿Hay alguna manera de guardar el historial de bash sin escribir exit? He configurado la configuración en "HISTCONTROL = erasedups"

que, en mi opinión, funciona mejor que ignorar los errores.

de todos modos, por alguna razón, no guardará los últimos comandos en el terminal bash a menos que escriba "exit". Estoy acostumbrado a hacer clic en la cruz en la ventana de terminal, así que siempre me molesta que los últimos comandos no se hayan guardado cuando vuelvo a iniciar sesión.

recordatorio: http://www.thegeekstuff.com/2008/08/15-examples-to-master-linux-command-line-history/#more-130

ColacX
fuente
Cuando se accede remotamente al terminal desde masilla, existe la opción de elegir cerrar ventana al salir: siempre. lo que me guarda la historia.
ColacX

Respuestas:

34

Bash History

Cualquier comando nuevo que se haya emitido en el terminal activo se puede agregar al .bash_historyarchivo con el siguiente comando:

history -a

El único concepto difícil de entender es que cada terminal tiene su propia lista de historial de bash (cargada desde el .bash_historyarchivo cuando abre el terminal)

Si desea extraer cualquier nuevo historial que hayan escrito otros terminales durante la vida útil de este terminal activo, puede agregar el contenido del .bash_history archivo a la lista del historial de bash activo

history -c;history -r

Esto borrará la lista de historial actual para que no obtengamos una lista repetida y anexemos el archivo de historial a la lista (ahora vacía).

Solución

Puede usar la variable bash PROMPT_COMMANDpara emitir un comando con cada nueva solicitud (cada vez que presiona enter en el terminal)

export PROMPT_COMMAND='history -a'

Esto registrará cada comando en el archivo de historial a medida que se emite.

Resultado

Ahora, cualquier terminal nueva que abra tendrá el historial de otras terminales sin tener que tener exitesas otras terminales. Este es mi flujo de trabajo preferido.

Más precisión

Digamos (por alguna razón) que tiene dos terminales que está usando simultáneamente y desea que el historial se refleje entre ambos para cada comando nuevo.

export PROMPT_COMMAND='history -a;history -c;history -r'

El principal inconveniente aquí es que es posible que deba presionar enter para volver a ejecutar PROMPT_COMMAND para obtener el historial más reciente del terminal opuesto.

Puede ver por qué esta opción más precisa es probablemente exagerada, pero funciona para ese caso de uso.

asincopación
fuente
esto es increíble para los flujos de trabajo adecuados ...
mate
1

No es una manera de ahorrar toda la historia de su golpe en un archivo separado , pero si usted está tratando de utilizar el mecanismo de la historia y por alguna razón no esté guardando toda su historia, que es una cuestión diferente.

Para guardar todo su historial en un archivo separado, siempre, pase lo que pase con el terminal

Un script proporcionado aquí hace el truco.

# don't put duplicate lines in the history. See bash(1) for more options
# ... and ignore same sucessive entries.
export HISTCONTROL=ignoreboth

# set the time format for the history file.
export HISTTIMEFORMAT="%Y.%m.%d %H:%M:%S "

# If this is an xterm set the title to user@host:dir
case "$TERM" in
  xterm*|rxvt*)
  # Show the currently running command in the terminal title:
  # http://www.davidpashley.com/articles/xterm-titles-with-bash.html
  show_command_in_title_bar()
  {
    case "$BASH_COMMAND" in
      *\033]0*)
      # The command is trying to set the title bar as well;
      # this is most likely the execution of $PROMPT_COMMAND.
      # In any case nested escapes confuse the terminal, so don't
      # output them.
      ;;
      *)
      if test ! "$BASH_COMMAND" = "log_bash_eternal_history"
      then
        echo -ne "\033]0;$(history 1 | sed 's/^ *[0-9]* *//') :: ${PWD} :: ${USER}@${HOSTNAME}\007"
      fi
      ;;
    esac
  }
  trap show_command_in_title_bar DEBUG
  ;;
  *)
  ;;
esac

log_bash_eternal_history()
{
  local rc=$?
  [[ $(history 1) =~ ^\ *[0-9]+\ +([^\ ]+\ [^\ ]+)\ +(.*)$ ]]
  local date_part="${BASH_REMATCH[1]}"
  local command_part="${BASH_REMATCH[2]}"
  if [ "$command_part" != "$ETERNAL_HISTORY_LAST" -a "$command_part" != "ls" -a "$command_part" != "ll" ]
  then
    echo $date_part $HOSTNAME $rc "$command_part" >> ~/.bash_eternal_history
    export ETERNAL_HISTORY_LAST="$command_part"
  fi
}

PROMPT_COMMAND="log_bash_eternal_history"

Para decirle al comando de historial "¡Guardar ahora!" al hacer clic en la X en una ventana de terminal virtual

Lo primero que debes entender es, ¿qué mecanismo usa tu emulador de terminal virtual para matar el bashproceso cuando sale? - Esto dependerá de qué emulador de terminal exacto esté usando.

Hay algunas opciones, y todas ellas involucran señales UNIX .

  • SIGTERM, SIGINT, SIGQUIT: el comportamiento predeterminado cuando Bash recibe una de estas señales en modo interactivo es ignorarla, por lo que probablemente no sea eso.

  • SIGHUP: esta señal normalmente hace que Bash finalice correctamente y realice la limpieza, pero no estoy seguro de si esa "limpieza" implica guardar el archivo de historial. Probablemente no.

  • SIGKILL, SIGSTOP: es imposible para Bash como proceso de espacio de usuario ignorar estas señales. El núcleo puede matar o detener por la fuerza el proceso en cualquier momento usando estas señales. Si su emulador de VT está enviando uno de estos, no podemos atraparlo y hacer algo antes de salir, por lo que no tiene suerte.

Algunas referencias: pregunta de ServerFault 337123

Pregunta Unix 6332

Uso de la historia de forma interactiva en el manual de GNU Bash

allquixotic
fuente