bash sauvegarder l'historique sans quitter


16

dans linux ubuntu bash terminal. existe-t-il un moyen de sauvegarder l'historique de bash sans écrire de sortie? j'ai mis la config sur "HISTCONTROL = erasedups"

qui, à mon avis, fonctionne mieux que les ignorés.

de toute façon, pour une raison quelconque, il ne sauvegardera pas les dernières commandes dans le terminal bash, sauf si je tape "exit". J'ai l'habitude de simplement cliquer sur la croix dans la fenêtre du terminal, donc je suis toujours ennuyé que les dernières commandes n'aient pas été enregistrées lorsque je me reconnecte.

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


lors de l'accès à distance au terminal à partir de mastic, il est possible de choisir de fermer la fenêtre à la sortie: toujours. ce qui sauve l'histoire pour moi.
ColacX

Réponses:


34

Histoire de Bash

Toute nouvelle commande émise dans le terminal actif peut être ajoutée au .bash_historyfichier avec la commande suivante:

history -a

Le seul concept délicat à comprendre est que chaque terminal a sa propre liste d' historique bash (chargée à partir du .bash_historyfichier lorsque vous ouvrez le terminal)

Si vous souhaitez extraire tout nouvel historique écrit par d'autres terminaux pendant la durée de vie de ce terminal actif, vous pouvez ajouter le contenu du .bash_history fichier à la liste d' historique de bash active

history -c;history -r

Cela effacera la liste d'historique actuelle afin que nous n'obtenions pas de liste répétée et ajoutons le fichier d'historique à la liste (maintenant vide).

Solution

Vous pouvez utiliser la variable bash PROMPT_COMMANDpour émettre une commande à chaque nouvelle invite (chaque fois que vous appuyez sur Entrée dans le terminal)

export PROMPT_COMMAND='history -a'

Cela enregistrera chaque commande dans le fichier historique au fur et à mesure de son émission.

Résultat

Maintenant, tout nouveau terminal que vous ouvrez aura l'historique des autres terminaux sans avoir à exitces autres terminaux. C'est mon flux de travail préféré.

Plus de précision

Disons (pour une raison quelconque) que vous avez deux terminaux que vous utilisez simultanément et que vous souhaitez que l'historique se reflète entre les deux pour chaque nouvelle commande.

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

Le principal inconvénient ici est que vous devrez peut-être appuyer sur Entrée pour réexécuter PROMPT_COMMAND afin d'obtenir la dernière historique du terminal opposé.

Vous pouvez voir pourquoi cette option plus précise est probablement exagérée, mais cela fonctionne pour ce cas d'utilisation.


c'est tellement génial pour des workflows appropriés ....
matt


1

Il existe un moyen de sauvegarder tout votre historique bash dans un fichier distinct , mais si vous essayez d'utiliser le mécanisme d'historique et que pour une raison quelconque il n'enregistre pas tout votre historique, c'est un problème différent.

Pour sauvegarder tout votre historique dans un fichier séparé, toujours, peu importe ce qui arrive au terminal

Un script fourni ici fait l'affaire.

# 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"

Pour dire à la commande d'historique "Enregistrer maintenant!" en cliquant sur le X dans une fenêtre de terminal virtuel

Tout d'abord, vous devez comprendre quel mécanisme votre émulateur de terminal virtuel utilise-t-il pour tuer le bashprocessus à sa sortie? - Cela dépendra de l'émulateur de terminal exact que vous utilisez.

Il existe quelques options, et toutes impliquent des signaux UNIX .

  • SIGTERM, SIGINT, SIGQUIT: Le comportement par défaut lorsque Bash reçoit l'un de ces signaux en mode interactif est de l'ignorer, donc ce n'est probablement pas ça.

  • SIGHUP: Ce signal provoque normalement la fin de Bash et le nettoyage, mais je ne sais pas si ce "nettoyage" implique l'enregistrement du fichier d'historique. Ce n'est probablement pas le cas.

  • SIGKILL, SIGSTOP: Il est impossible pour Bash en tant que processus de l'espace utilisateur d'ignorer ces signaux. Le noyau peut à tout moment tuer ou arrêter le processus de force en utilisant ces signaux. Si votre émulateur VT envoie l'un de ceux-ci, nous ne pouvons pas le piéger et faire quelque chose avant de quitter, donc vous n'avez pas de chance.

Quelques références: ServerFault question 337123

Question Unix 6332

Utilisation interactive de l'historique dans le manuel GNU Bash

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.