bash zapisz historię bez wyjścia

16

w terminalu Linuksa Ubuntu bash. czy jest jakiś sposób na zapisanie historii basha bez pisania wyjścia? ustawiłem config na „HISTCONTROL = wymazane”

które moim zdaniem działa lepiej niż ignorowane.

tak czy inaczej z jakiegoś powodu nie zapisze kilku ostatnich poleceń w terminalu bash, chyba że wpisuję „exit”. Zwykle klikam krzyżyk w oknie terminala, więc zawsze denerwuję się, że ostatnie polecenia nie zostały zapisane podczas ponownego logowania.

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

ColacX
źródło
przy zdalnym dostępie do terminala z kitu istnieje możliwość wyboru zamknięcia okna przy wyjściu: zawsze. co zapisuje mi historię.
ColacX

Odpowiedzi:

35

Historia Bash

Wszelkie nowe polecenia wydane w aktywnym terminalu można dołączyć do .bash_historypliku za pomocą następującego polecenia:

history -a

Jedyną trudną do zrozumienia koncepcją jest to, że każdy terminal ma własną listę historii bash (ładowaną z .bash_historypliku po otwarciu terminalu)

Jeśli chcesz wyciągnąć żadnych nowych historii, który został napisany przez innych terminali w trakcie trwania tego aktywnego terminala można dołączyć zawartość .bash_history pliku historii aktywny bash listy

history -c;history -r

Spowoduje to wyczyszczenie bieżącej listy historii, dzięki czemu nie otrzymamy powtarzającej się listy, i dołączenie pliku historii do (teraz pustej) listy.

Rozwiązanie

Możesz użyć zmiennej bash, PROMPT_COMMANDaby wydać polecenie przy każdym nowym pytaniu (za każdym razem, gdy naciśniesz enter w terminalu)

export PROMPT_COMMAND='history -a'

Spowoduje to zapisanie każdego polecenia do pliku historii w momencie jego wydania.

Wynik

Teraz każdy nowy terminal, który otworzysz, będzie miał historię innych terminali bez konieczności korzystania z exitnich. To jest mój preferowany przepływ pracy.

Większa precyzja

Załóżmy (z jakiegoś powodu), że masz dwa terminale, których używasz jednocześnie i chcesz, aby historia odzwierciedlała oba z nich dla każdego nowego polecenia.

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

Główną wadą jest to, że może być konieczne naciśnięcie klawisza Enter, aby ponownie uruchomić PROMPT_COMMAND, aby uzyskać najnowszą historię z przeciwnego terminala.

Możesz zobaczyć, dlaczego ta bardziej precyzyjna opcja jest prawdopodobnie przesadna, ale działa w tym przypadku użycia.

asynchronizacja
źródło
to jest niesamowite dla prawidłowego przepływu pracy ...
Matt
2

Aby zapisać historię bash do pliku:

history -w ~/history.txt
vim ~/history.txt

Eksportuje historię do pliku o nazwie history.txt. Następnie możesz go wyświetlić za pomocą swojego ulubionego edytora.

Odpowiedź skopiowana z http://tech.karbassi.com/2007/01/14/view-and-change-bash-history/

umbersar
źródło
1

Nie jest to sposób, aby zapisać całą historię swoją bash w osobnym pliku , ale jeśli próbują wykorzystać mechanizm historii iz jakiegoś powodu nie zapisuje całą historię, to jest inna sprawa.

Aby zapisać całą historię w osobnym pliku, zawsze, bez względu na to, co stanie się z terminalem

Skrypt podany tutaj załatwia sprawę.

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

Aby powiedzieć historii polecenie „Zapisz teraz!” po kliknięciu X w oknie wirtualnego terminalu

Po pierwsze, musisz zrozumieć, z jakiego mechanizmu korzysta Twój emulator terminala wirtualnego, aby zabić bashproces po jego zakończeniu ? - Będzie to zależeć od tego, jakiego dokładnie emulatora terminala używasz.

Istnieje kilka opcji, a wszystkie z nich obejmują sygnały UNIX .

  • SIGTERM, SIGINT, SIGQUIT: Domyślnym zachowaniem, gdy Bash odbiera jeden z tych sygnałów w trybie interaktywnym, jest ignorowanie go, więc prawdopodobnie tak nie jest .

  • SIGHUP: Ten sygnał zwykle powoduje, że Bash kończy się z gracją i wykonuje czyszczenie, ale nie jestem pewien, czy to „czyszczenie” wymaga zapisania pliku historii. Prawdopodobnie nie.

  • SIGKILL, SIGSTOP: Bash jako proces przestrzeni użytkownika nie może zignorować tych sygnałów. Jądro może siłą zabić lub zatrzymać proces w dowolnym momencie za pomocą tych sygnałów. Jeśli twój emulator VT wysyła jeden z nich, nie możemy go uwięzić i zrobić czegoś przed wyjściem, więc nie masz szczęścia.

Kilka odniesień: Pytanie ServerFault 337123

Pytanie uniksowe 6332

Interaktywne korzystanie z historii w podręczniku GNU Bash

allquixotic
źródło