bash salva la cronologia senza uscire


16

nel terminale Ubuntu Bash di Linux. c'è un modo per salvare la cronologia di bash senza scrivere exit? ho impostato la configurazione su "HISTCONTROL = cancellati"

che secondo me funziona meglio di ignoredups.

comunque per qualche motivo non salverà gli ultimi comandi nel terminale bash a meno che non digiti "exit". Sono abituato a fare clic sulla croce sulla finestra del terminale, quindi sono sempre seccato che gli ultimi comandi non siano stati salvati quando eseguo di nuovo l'accesso.

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


quando si accede in remoto al terminale da putty c'è la possibilità di scegliere chiudi finestra all'uscita: sempre. che salva la storia per me.
ColacX,

Risposte:


34

Storia di Bash

Eventuali nuovi comandi che sono stati emessi nel terminale attivo possono essere aggiunti al .bash_historyfile con il seguente comando:

history -a

L'unico concetto difficile da capire è che ogni terminale ha il suo elenco di cronologia bash (caricato dal.bash_history file quando si apre il terminale)

Se si desidera estrarre qualsiasi nuova cronologia che è stata scritta da altri terminali durante la vita di questo terminale attivo, è possibile aggiungere il contenuto del .bash_history file all'elenco della cronologia bash attivo

history -c;history -r

Questo cancellerà l'elenco storico corrente in modo da non ottenere un elenco ripetuto e aggiungere il file cronologico all'elenco (ora vuoto).

Soluzione

È possibile utilizzare la variabile bash PROMPT_COMMANDper emettere un comando con ogni nuovo prompt (ogni volta che si preme invio nel terminale)

export PROMPT_COMMAND='history -a'

Ciò registrerà ogni comando nel file della cronologia mentre viene emesso.

Risultato

Ora qualsiasi nuovo terminale che aprirai avrà la storia di altri terminali senza doverlo fare exit quegli altri terminali. Questo è il mio flusso di lavoro preferito.

Più precisione

Diciamo (per qualche motivo) che hai due terminali che stai usando contemporaneamente e vuoi che la cronologia rifletta tra entrambi per ogni nuovo comando.

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

Lo svantaggio principale qui è che potrebbe essere necessario premere Invio per rieseguire PROMPT_COMMAND per ottenere la cronologia più recente dal terminale opposto.

Puoi capire perché questa opzione più precisa è probabilmente eccessiva, ma funziona per quel caso d'uso.


è fantastico per i flussi di lavoro corretti ....
matt


1

V'è un modo per salvare tutta la storia la vostra bash in un file separato , ma se si sta tentando di utilizzare il meccanismo di storia e per qualche motivo non è salvare tutta la vostra storia, che è una questione diversa.

Per salvare tutta la cronologia in un file separato, sempre, qualunque cosa accada al terminale

Uno script fornito qui fa il trucco.

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

Per dire al comando di cronologia "Salva ora!" quando si fa clic sulla X in una finestra del terminale virtuale

Prima di tutto quello che devi capire è quale meccanismo usa l'emulatore di terminale virtuale per terminare il bashprocesso quando esce? - Questo dipenderà dall'esatto emulatore di terminale che stai utilizzando.

Ci sono alcune opzioni e tutte coinvolgono i segnali UNIX .

  • SIGTERM, SIGINT, SIGQUIT: il comportamento predefinito quando Bash riceve uno di questi segnali in modalità interattiva è ignorarlo, quindi probabilmente non è quello.

  • SIGHUP: Questo segnale di solito fa terminare graziosamente Bash e ripulire, ma non sono sicuro che quel "cleanup" comporti il ​​salvataggio del file della cronologia. Probabilmente no.

  • SIGKILL, SIGSTOP: È impossibile per Bash come processo di spazio utente ignorare questi segnali. Il kernel può uccidere o interrompere forzatamente il processo in qualsiasi momento usando questi segnali. Se il tuo emulatore VT sta inviando uno di questi, non possiamo intrappolarlo e fare qualcosa prima di uscire, quindi sei sfortunato.

Alcuni riferimenti: domanda ServerFault 337123

Domanda Unix 6332

Uso interattivo della storia nel manuale di GNU Bash

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.