종료하지 않고 bash 저장 기록


16

리눅스 우분투 bash 터미널에서. exit를 쓰지 않고 bash 기록을 저장하는 방법이 있습니까? 설정을 "HISTCONTROL = erasedups"로 설정했습니다

내 의견으로는 무시하는 것보다 잘 작동합니다.

어쨌든 어떤 이유로 "exit"을 입력하지 않으면 bash 터미널에 마지막 몇 명령을 저장하지 않습니다. 터미널 창에서 십자 표시를 클릭하는 데 익숙하므로 다시 로그인 할 때 마지막 명령이 저장되지 않은 것이 항상 짜증납니다.

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


퍼티에서 터미널에 원격으로 액세스 할 때 종료시 창 닫기를 선택하는 옵션이 있습니다. 항상. 그것은 나를 위해 역사를 저장합니다.
ColacX

답변:


35

배쉬 역사

활성 터미널에서 발행 된 모든 새 명령 .bash_history은 다음 명령으로 파일에 추가 될 수 있습니다 .

history -a

이해하기 어려운 까다로운 개념은 각 터미널마다 고유 한 bash 기록 목록 ( .bash_history터미널을 열 때 파일 에서로드 됨 )이 있다는 것입니다.

이 활성 터미널의 수명 동안 다른 터미널에서 작성된 새 기록을 가져 오려면 .bash_history 파일 내용을 활성 bash 기록 목록에 추가 할 수 있습니다

history -c;history -r

이렇게하면 현재 히스토리 목록이 지워 지므로 반복 된 목록이 표시되지 않으며 히스토리 파일이 (현재 비어있는) 목록에 추가됩니다.

해결책

bash 변수 PROMPT_COMMAND를 사용하여 새 프롬프트마다 명령을 실행할 수 있습니다 (터미널에서 Enter를 누를 때마다)

export PROMPT_COMMAND='history -a'

이것은 각 명령 이 발행 될 때 히스토리 파일 에 기록 됩니다 .

결과

이제 새로운 터미널을 열면 다른 터미널에 관계없이 다른 터미널의 이력이 exit생깁니다. 이것이 내가 선호하는 워크 플로우입니다.

더 정밀한

(어떤 이유로 든) 동시에 사용하고있는 두 개의 터미널이 있고 각각의 새 명령에 대해 기록이 두 터미널 사이에 반영되기를 원한다고합시다.

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

여기서 주요 단점은 반대 터미널에서 최신 히스토리를 가져 오려면 Enter 키를 눌러 PROMPT_COMMAND를 다시 실행해야 할 수도 있다는 것입니다.

왜 이보다 정확한 옵션이 과도하게 사용되는지 알 수 있지만 해당 사용 사례에서 작동합니다.


이것은 적절한 워크 플로우를 위해 정말 대단합니다 ....
matt matt


1

입니다 모든 bash는 기록을 저장하는 방법을 별도의 파일로는 ,하지만 당신은 역사 메커니즘을 사용하려고하고 어떤 이유로이 모든 기록을 저장하지 않은 경우, 그것은 다른 문제입니다.

터미널에 무슨 일이 있어도 모든 이력을 별도의 파일로 저장하려면

여기에 제공된 스크립트 가 트릭을 수행합니다.

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

기록 명령 "지금 저장!" 가상 터미널 창에서 X를 클릭 할 때

먼저 이해해야 할 것은 가상 터미널 에뮬레이터가 bash프로세스가 종료 될 때 프로세스를 종료 하는 데 사용하는 메커니즘은 무엇 입니까? -사용중인 정확한 터미널 에뮬레이터에 따라 다릅니다.

몇 가지 옵션이 있으며 모두 UNIX 신호 와 관련됩니다 .

  • SIGTERM, SIGINT, SIGQUIT : Bash가 대화식 모드에서 이러한 신호 중 하나를 수신 할 때의 기본 동작은 무시하는 것이므로 아마도 그렇지 않습니다.

  • SIGHUP :이 신호는 일반적으로 Bash가 정상적으로 종료되고 정리를 수행하지만 "정리"에 히스토리 파일 저장이 있는지 확실하지 않습니다. 아마 그렇지 않습니다.

  • SIGKILL, SIGSTOP : Bash가 사용자 공간 프로세스로서 이러한 신호를 무시하는 것은 불가능합니다. 커널은 이러한 신호를 사용하여 언제든지 프로세스를 강제 종료하거나 중지 할 수 있습니다. VT 에뮬레이터가이 중 하나를 전송하는 경우 종료하기 전에 트랩을 잡고 무언가를 수행 할 수 없으므로 운이 없습니다.

몇 가지 참조 : ServerFault 질문 337123

유닉스 질문 6332

GNU Bash 매뉴얼에서 대화식으로 역사 사용하기

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.