여러 터미널 창에서 bash 기록 유지


526

일관되게 두 개 이상의 터미널이 열려 있습니다. 다양한 비트와 밥을하는 2에서 10 사이. 이제 다시 시작하고 다른 터미널 세트를 연다 고 가정 해 봅시다. 어떤 사람들은 특정한 것을 기억하고 어떤 사람들은 잊어 버립니다.

나는 다음과 같은 역사를 원한다.

  • 모든 터미널에서 모든 것을 기억
  • 모든 터미널에서 즉시 액세스 할 수 있습니다 (예 : ls하나의 터미널에서 이미 실행중인 다른 터미널로 전환 한 다음 위로 누르면 ls표시됨)
  • 명령 앞에 공백이 있으면 명령을 잊지 않습니다.

배쉬가 그렇게 작동하도록 할 수있는 일이 있습니까?


57
나는 그것의 장점을 볼 수 있지만 개인적으로 나는 내 껍질에서 그것을 싫어할 것입니다. 나는 보통 매우 구체적인 용도로 터미널에 3 개 또는 4 개의 탭을 열어 둡니다. 하나는 'make'를 실행하고 하나는 vi를 사용하고 하나는 vi를 사용하고 다른 하나는 물건을 실행합니다. '등이 나타납니다. 이것은 나에게 매우 생산적입니다. 갑자기 갑자기 'make'탭으로 가서 치고 임의의 grep 명령이 표시되면 정말 화가납니다! 그래도 개인적인 메모
axel_c 13:26의

4
@axel_c 그것은 충분히 사실입니다. 기존 터미널은 자신의 기록 만 볼 수 있지만 새로운 터미널은 시간순으로 정확한 명령 목록을 볼 수있는 지능적인 방법을 생각할 수 없습니다.
Oli

8
@Oli는 "기존 터미널은 자신의 기록 만 볼 수 있지만 새로운 터미널은 시간순으로 정확한 명령 목록을 볼 수있는 지능적인 방법을 생각할 수 없다"고 썼다. 어떻습니까 export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"? 기존 쉘은 새 쉘이 볼 수 있도록 각 명령을 히스토리 파일에 추가하지만 자체 히스토리 만 표시합니다.
Chris 페이지

2
히스토리를 모두 별도로 저장하거나 모두 단일 히스토리 파일로 병합 하시겠습니까?
kbyrd

3
짧은 대답은 배쉬 개발자가 의도 한 것이 아닙니다. 기록을 플러시하고 다시 읽는 것에 기반한 솔루션은 아마도 효과가 있지만 Shlemiel The Painter를 조심하십시오 . 간단히 말해서 : 각 명령 사이의 처리 작업량은 히스토리 크기에 비례합니다.
Stéphane Gourichon

답변:


329

~ / .bashrc에 다음을 추가하십시오

# Avoid duplicates
export HISTCONTROL=ignoredups:erasedups  
# When the shell exits, append to the history file instead of overwriting it
shopt -s histappend

# After each command, append to the history file and reread it
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

20
이 PROMPT_COMMAND 솔루션의 문제점은 각 명령 후에 각 히스토리 항목의 숫자가 변경된다는 것입니다. rm 명령을 실행할 수 있습니다 ...
크리스 킴턴

2
나는이 작업을 수행 할 때 나는 i를 눌러에 명령을 발행 할 때까지 '업'할 때, 다른 이미 오픈 터미널은 마지막으로 입력 된 명령이없는 터미널 -이 예상된다? 그렇다면 다른 터미널의 기록을 즉시 즉시 수정할 수있는 방법이 있습니까?
Suan

7
@Suan, 이것은 명령을 기반으로 나에게 맞는 것 같습니다. 기록을 업데이트하기 위해 null 명령을 입력 할 수 있습니다 (Enter 키를 누르십시오).
세이지

3
실제로 history -a(...)는 질문 Bash history : "ignoredups"및 "erasedups"설정 에 대한 답변 에 따라 중복 지우기를 트리거하지 않습니다 . 이 답변은 설정 과 함께 작동하는 명령 시퀀스도 제공합니다 . history -<option>HISTCONTROL=ignoredups:erasedups
Piotr Dobrogost

23
에 이유가 없다 및 변수 : 당신은 그들을 정의하는 그래서 그들은이 (또한 낭비도 대화 형이 아닌 사람의) 모든 쉘에서 정의됩니다. exportHISTCONTROLPROMPT_COMMAND.bashrc
dolmen

248

그래서 이것은 내 역사와 관련된 .bashrc것입니다.

export HISTCONTROL=ignoredups:erasedups  # no duplicate entries
export HISTSIZE=100000                   # big big history
export HISTFILESIZE=100000               # big big history
shopt -s histappend                      # append to history, don't overwrite it

# Save and reload the history after each command finishes
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Mac OS X 10.5의 bash 3.2.17, 10.6의 bash 4.1.7로 테스트되었습니다.


3
흠 .. 명령 번호가 모든 프롬프트를 변경하기 때문에 $! 34를 사용할 수 없게됩니다. @Davide @Schof @kch에 대한 해결 방법이 있습니까?

5
무한 역사를 얻으려면 이것을 사용하십시오 : 영원한 역사를 강타하십시오 . 그러나 이것은 자동으로 다시로드되지 않기 때문에 위의 코드에 무료입니다.

7
참고 여기에 언급 된 솔루션 중 어느 것도 다음 문제를 해결할 수 없습니다. 셸 창 A와 B가 두 개 있습니다. 셸 창 A에서을 실행 sleep 9999하고 셸 창 B에서 (수면이 끝날 때까지 기다리지 않고) sleep 9999bash 기록에서 볼 수 있기를 원합니다 .
pts

1
@ pts 나도 라이브 행동을 목표로하고 있었지만 다른 터미널에서 다른 일을 더 쉽게 수행 할 수있는 터미널 특정 기록을 갖는 것이 더 편리하다는 것을 깨달았습니다. 나는이 매우 유용하다는 것을 발견 stackoverflow.com/questions/338285/#answer-7449399 그 바탕으로, 나 자신이라는 별칭을 만든 href즉시 내 현재 터미널의 역사를 새로 고쳐 과정에서 기록 파일을 정리합니다. 새 터미널을 열 때마다 해당 정리 / 동기화가 bashrc 파일에서 실행되므로 새 터미널에 최신 기록이 있습니다. 나는 그것을 함께 사용하고 있습니다history -a
trusktr

6
에 이유가 없다 export변수 : 당신은 그들을 정의하는 .bashrc그래서 그들은이 (낭비도에도 대화 형이 아닌 사람의) 모든 쉘에서 정의 될 것이다
고인돌이

118

Bash 세션 히스토리 공유에 대한 나의 시도는 다음과 같습니다. 이를 통해 히스토리 카운터가 섞이지 않고 히스토리 확장 !number이 작동 하는 방식으로 bash 세션간에 히스토리 공유가 가능 합니다 (일부 제한 사항이 있음).

Ubuntu 10.04 LTS (Lucid Lynx)에서 Bash 버전 4.1.5 사용

HISTSIZE=9000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

_bash_history_sync() {
    builtin history -a         #1
    HISTFILESIZE=$HISTSIZE     #2
    builtin history -c         #3
    builtin history -r         #4
}

history() {                  #5
    _bash_history_sync
    builtin history "$@"
}

PROMPT_COMMAND=_bash_history_sync

설명:

  1. 방금 입력 한 줄을 $HISTFILE(기본값은 .bash_history)에 추가하십시오 . 이것은 $HISTFILE한 줄씩 자랄 것 입니다.

  2. 특수 변수 $HISTFILESIZE를 특정 값으로 설정하면 가장 오래된 항목을 제거하여 Bash가 $HISTFILE더 이상 $HISTFILESIZE줄 보다 잘리지 않습니다 .

  3. 실행중인 세션 기록을 지우십시오. 이렇게하면 기록 카운터의 양이 줄어 듭니다 $HISTSIZE.

  4. 내용을 읽고 $HISTFILE현재 실행중인 세션 기록에 삽입하십시오. 그러면의 행 수가 기록 카운터를 증가시킵니다 $HISTFILE. 행 개수 $HISTFILE가 반드시 필요한 것은 아닙니다 $HISTFILESIZE.

  5. history()기능은 내장 히스토리를 대체하여 히스토리가 표시되기 전에 동기화되었는지 확인합니다. 이것은 숫자로 히스토리 확장에 필요합니다 (자세한 내용은 나중에 참조).

자세한 설명 :

  • 1 단계는 현재 실행중인 세션의 명령이 글로벌 히스토리 파일에 기록되도록합니다.

  • 4 단계는 다른 세션의 명령이 현재 세션 히스토리로 읽히도록합니다.

  • 4 단계는 기록 카운터를 높이기 때문에 어떤 방식 으로든 카운터를 줄여야합니다. 이것은 3 단계에서 수행됩니다.

  • 3 단계에서 기록 카운터가만큼 줄어 듭니다 $HISTSIZE. 단계 4에서 히스토리 카운터는의 행 수만큼 증가합니다 $HISTFILE. 2 단계에서 줄 수 $HISTFILE는 정확히 일치 해야합니다 $HISTSIZE( 이것은와 $HISTFILESIZE동일해야 함을 의미 합니다 $HISTSIZE).

히스토리 확장의 제한 조건 정보 :

수에 의하여 역사 확장을 사용하는 경우, 당신은해야한다 항상 숫자를 찾아 바로 사용하기 전에. 즉, 번호 조회와 사용 사이에 bash 프롬프트가 표시되지 않습니다. 그것은 일반적으로 enter와 ctrl + c가 없음을 의미합니다.

일반적으로 Bash 세션이 둘 이상 있으면 번호 별 히스토리 확장이 두 개의 Bash 프롬프트 표시간에 값을 유지한다고 보장 할 수 없습니다. when PROMPT_COMMAND가 실행될 때 다른 모든 Bash 세션의 기록이 현재 세션의 기록에 통합되기 때문입니다. 다른 bash 세션에 새 명령이 있으면 현재 세션의 기록 번호가 달라집니다.

나는이 제약이 합리적이라고 생각한다. 임의의 이력 번호를 기억할 수 없으므로 어쨌든 매번 번호를 찾아야합니다.

일반적으로 이처럼 숫자로 기록 확장을 사용합니다

$ history | grep something #note number
$ !number

다음 Bash 옵션을 사용하는 것이 좋습니다.

## reedit a history substitution line if it failed
shopt -s histreedit
## edit a recalled history line before executing
shopt -s histverify

이상한 버그 :

히스토리 명령을 파이프로 실행하면 해당 명령이 히스토리에 두 번 나열됩니다. 예를 들면 다음과 같습니다.

$ history | head
$ history | tail
$ history | grep foo
$ history | true
$ history | false

모든 기록에 두 번 나열됩니다. 왜 그런지 모르겠습니다.

개선을위한 아이디어 :

  • _bash_history_sync()매번 실행되지 않도록 기능을 수정하십시오 . 예를 들어 CTRL+C프롬프트 후에는 실행하면 안됩니다 . 나는 종종 CTRL+C그 줄을 실행하고 싶지 않다고 결정할 때 긴 명령 줄을 버리는 데 사용 합니다. 때로는 CTRL+CBash 완료 스크립트를 중지하는 데 사용해야 합니다.

  • 현재 세션의 명령은 항상 현재 세션 기록에서 가장 최신이어야합니다. 이것은 또한 주어진 이력 번호가이 세션의 이력 항목 값을 유지한다는 부작용이 있습니다.


1
왜 "history -c; history -r"대신 "history -n"(로드를 다시로드하지 않은)?
Graham

@ Graham : history -n역사 카운터를 엉망으로 만들기 때문에 사용하고 싶지 않았습니다 . 또한, 나는 history -n너무 신뢰할 수없는 것으로 나타났습니다 .
lesmana

1
한 가지 단점 : 여러 줄 문자열이있는 명령은 일반적으로 현재 세션에서 여전히 유지됩니다. 이 트릭을 사용하면 개별 라인으로 즉시 분할됩니다. -c -r에 -n을 사용하면 cmdhist 나 lithist도 도움이되지 않습니다. 현재로서는 해결 방법이 없다고 생각합니다.
Jo Liss

24
이것을 조금 시도한 후에 실제로 및 history -a없이, 을 실행하는 것이 유용성 측면에서 더 나은 것으로 나타났습니다 (질문이 요청한 것은 아닙니다). 즉, 현재 셸을 종료하기 전에 새 셸에서 실행하는 명령을 즉시 사용할 수 있지만 동시에 실행되는 셸에서는 사용할 수 없습니다. 이 방법으로 Arrow-Up은 항상 현재 세션 의 마지막 실행 명령 선택 하므로 혼란스럽지 않습니다. -c-r
Jo Liss

뛰어난 답변, 이것은 일반적인 "역사 -a; 역사 -n"과 달리 안정적으로 작동
RichVel

42

을 사용하는 방법을 모르겠습니다 bash. 그러나의 가장 인기있는 기능 중 하나입니다 zsh.
필자는 개인적으로 선호하는 zsh동안 bash그래서 그것을 시도하는 것이 좋습니다.

.zshrc역사를 다루는 부분은 다음과 같습니다 .

SAVEHIST=10000 # Number of entries
HISTSIZE=10000
HISTFILE=~/.zsh/history # File
setopt APPEND_HISTORY # Don't erase history
setopt EXTENDED_HISTORY # Add additional data to history like timestamp
setopt INC_APPEND_HISTORY # Add immediately
setopt HIST_FIND_NO_DUPS # Don't show duplicates in search
setopt HIST_IGNORE_SPACE # Don't preserve spaces. You may want to turn it off
setopt NO_HIST_BEEP # Don't beep
setopt SHARE_HISTORY # Share history between session/terminals


16

이렇게하려면 두 줄을 추가해야합니다 ~/.bashrc.

shopt -s histappend
PROMPT_COMMAND="history -a;history -c;history -r;$PROMPT_COMMAND"

보낸 사람 man bash:

histappend shell 옵션이 활성화 된 경우 (아래의 SHELL BUILTIN COMMANDS 아래에서 shopt 설명 참조) 행이 내역 파일에 추가되고, 그렇지 않으면 내역 파일을 덮어 씁니다.


10

Muerr가 제안한 "history -a"및 "history -r"을 실행하도록 BASH 프롬프트를 편집 할 수 있습니다.

savePS1=$PS1

(당신이 무언가를 엉망으로 만드는 경우가 거의 보장됩니다)

PS1=$savePS1`history -a;history -r`

(이것은 백틱입니다. 모든 프롬프트에서 history -a 및 history -r을 실행합니다. 텍스트가 출력되지 않으므로 프롬프트가 변경되지 않습니다.

PS1 변수를 원하는 방식으로 설정했으면 ~ / .bashrc 파일에서 영구적으로 설정하십시오.

테스트하는 동안 원래 프롬프트로 돌아가려면 다음을 수행하십시오.

PS1=$savePS1

나는 그것이 일종의 작동을 보장하기 위해 이것에 대한 기본 테스트를 수행했지만 history -a;history -r모든 프롬프트 에서 실행되는 부작용에 대해서는 말할 수 없습니다 .


2
kch의 솔루션은 내 것보다 잘 작동합니다. 나는 이제 내 .bashrc에서 그의 솔루션을 사용하고 있습니다.

9

아래 문제를 해결하는 bash 또는 zsh 기록 동기화 솔루션이 필요한 경우 http://ptspts.blogspot.com/2011/03/how-to-automatically-synchronize-shell.html 에서 참조 하십시오.

문제는 다음과 같습니다. 쉘 창 A와 B가 두 개 있습니다. 쉘 창 A에서을 실행 sleep 9999하고 쉘 창 B에서 (잠자기가 끝날 때까지 기다리지 않고) sleep 9999bash 기록에서 볼 수 있기를 원합니다 .

대부분의 다른 솔루션은 여기에이 문제를 해결하지 않을 이유는 그들이 사용하여 기록 파일에 그들의 역사의 변화를 작성하는 것입니다 PROMPT_COMMAND또는 PS1유일한 후, 너무 늦게 실행중인 둘, sleep 9999명령이 완료되었습니다.


1
이것은 좋은 해결책이지만 몇 가지 질문이 있습니다. 1. 원본 .bash_history 파일을 사용할 수 있습니까? $ HOME에 존재하는 다른 bash 기록 파일을 원하지 않습니다. 2. 이것에 대해 github 저장소를 설정하는 것이 좋습니다.
weynhamz

디버그 훅이 bashdb와 충돌하는 것 같습니다 .bash 세션을 시작할 때마다 다음과 같은 결과가 출력됩니다. ```bash 디버거, bashdb, 릴리스 4.2-0.8 Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Rocky Bernstein 이것은 GNU 일반 공중 사용 허가서에 포함 된 무료 소프트웨어이며 귀하는 다음을 환영합니다. 특정 조건 하에서 변경 및 / 또는 사본을 배포합니다. ** 내부 디버그 오류 _Dbg_is_file () : 파일 인수 null bash : _Dbg_filenames [$ fullname] : 잘못된 배열 첨자```
weynhamz

@Techlive Zheng : 1. .merged_bash_history가 다른 파일 형식을 사용하기 때문에 원래의 .bash_history는 의도적으로 지원되지 않습니다. 설계에 의한 견고성, 그대로 유지됩니다. 2. github repo는 일반적으로 좋은 생각이지만,이 프로젝트를 위해 그것을 유지할 시간이 없기 때문에 그렇게하지 않습니다. -예, bashdb와 충돌하며 쉬운 해결책이 없습니다 (동일한 후크를 사용합니다). 수정 작업을 할 계획은 없지만 패치를 수락합니다.
pts

좋아 감사합니다. 나는 훨씬 간단하고 더 나은 sulotion을 생각해 냈습니다.
weynhamz

@TechliveZheng : 간단하고 더 나은 솔루션을 우리와 공유하여 모두가 배울 수 있도록 하시겠습니까? (그렇다면 질문에 대한 답변을 추가하십시오.)
pts

8

당신이 사용할 수있는 history -a다음의 HISTFILE에 현재 세션의 역사를 추가 사용 history -rHISTFILE을 읽을 수있는 다른 터미널에. 


8

맞습니다. 그래서 마침내 이것은 적절한 해결책을 찾기 위해 짜증났습니다.

# Write history after each command
_bash_history_append() {
    builtin history -a
}
PROMPT_COMMAND="_bash_history_append; $PROMPT_COMMAND"

이것이하는 일은이 스레드에서 말한 것에 대한 일종의 융합입니다. 단, 모든 명령 후에 왜 세계 역사를 다시로드 할 것인지 이해할 수 없습니다. 다른 터미널에서 일어나는 일에 대해서는 거의 신경 쓰지 않지만 항상 한 터미널에서 일련의 명령을 실행합니다.

make
ls -lh target/*.foo
scp target/artifact.foo vm:~/

(간단한 예)

그리고 또 다른 :

pv ~/test.data | nc vm:5000 >> output
less output
mv output output.backup1

어떤 방법으로도 명령을 공유하고 싶지 않습니다.


1
모든 명령 후에 기록을 다시로드하는 이유는 질문에 필요한 동작이기 때문입니다 (따라서 실제로 질문에 대한 질문에 답변하지는 않습니다).
마이클 호머

2
@MichaelHomer 페어 포인트. 답을 내려 놓으면 답이 맨 아래에 머물러 있지만, 요청 된 동작이 얼마나 나쁜지 알지 못하고 OPP에 초크하게 만들 것입니다.
Yarek T

3
여기에 그렇습니다, 그것은 공정한 타협입니다. 나의 주요 불만은 내가 역사를 잃고 있다는 것입니다. 동시 세션에서 즉각적인 업데이트를 의미하지 않더라도이를 중지해야합니다.
Oli

7

내가 사용하는 대안이 있습니다. 번거롭지 만 때로는 @axel_c가 각 터미널에 별도의 기록 인스턴스를 만들고 싶을 수도있는 문제를 해결합니다 (하나는 모니터링, 하나는 vim 등).

지속적으로 업데이트하는 별도의 추가 기록 파일을 유지합니다. 다음은 핫키에 매핑되었습니다.

history | grep -v history >> ~/master_history.txt

이것은 현재 터미널의 모든 히스토리를 홈 디렉토리의 master_history.txt 파일에 추가합니다.

마스터 히스토리 파일을 검색하는 별도의 단축키가 있습니다.

cat /home/toby/master_history.txt | grep -i

나는 고양이를 사용한다 | grep은 정규식에 들어가기 위해 커서를 끝에 둡니다. 덜 추한 방법은이 작업을 수행하기 위해 경로에 몇 가지 스크립트를 추가하는 것이지만 단축키는 내 목적으로 작동합니다. 또한 정기적으로 작업 한 다른 호스트에서 내역을 가져 와서 해당 내역을 master_history.txt 파일에 추가합니다.

사용한 까다로운 정규 표현식이나 7 개월 전에 나온 이상한 펄 원 라이너를 신속하게 검색하고 찾을 수 있다는 것이 항상 좋습니다.


6

마지막 수정 사항을 제공 할 수 있습니다. env 변수 HISTCONTROL이 "ignorespace"(또는 "ignoreboth")를 지정하지 않았는지 확인하십시오.

그러나 여러 동시 세션으로 고통을 느낍니다. bash에서는 단순히 잘 처리되지 않습니다.


6

@lesmana의 답변을 향상 시켰습니다 . 가장 큰 차이점은 동시 창은 기록을 공유하지 않는다는 것입니다. 즉, 다른 창에 대한 컨텍스트를 현재 창에로드하지 않고도 창에서 계속 작업 할 수 있습니다.

'히스토리'를 명시 적으로 입력하거나 새 창을 열면 이전의 모든 창에서 히스토리가 표시됩니다.

또한 이 전략 을 사용 하여 내 컴퓨터에 입력 한 모든 명령을 보관합니다.

# Consistent and forever bash history
HISTSIZE=100000
HISTFILESIZE=$HISTSIZE
HISTCONTROL=ignorespace:ignoredups

_bash_history_sync() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
}

_bash_history_sync_and_reload() {
  builtin history -a         #1
  HISTFILESIZE=$HISTSIZE     #2
  builtin history -c         #3
  builtin history -r         #4
}

history() {                  #5
  _bash_history_sync_and_reload
  builtin history "$@"
}

export HISTTIMEFORMAT="%y/%m/%d %H:%M:%S   "
PROMPT_COMMAND='history 1 >> ${HOME}/.bash_eternal_history'
PROMPT_COMMAND=_bash_history_sync;$PROMPT_COMMAND

5

여러 사람이 동일한 서버에서 작업 할 수 있으므로 기록을 tty 당 파일에 넣기로 결정했습니다. 각 세션의 명령을 분리하면 감사하기가 더 쉽습니다.

# Convert /dev/nnn/X or /dev/nnnX to "nnnX"
HISTSUFFIX=`tty | sed 's/\///g;s/^dev//g'`
# History file is now .bash_history_pts0
HISTFILE=".bash_history_$HISTSUFFIX"
HISTTIMEFORMAT="%y-%m-%d %H:%M:%S "
HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
HISTSIZE=1000
HISTFILESIZE=5000

역사는 이제 다음과 같습니다 :

user@host:~# test 123
user@host:~# test 5451
user@host:~# history
1  15-08-11 10:09:58 test 123
2  15-08-11 10:10:00 test 5451
3  15-08-11 10:10:02 history

파일은 다음과 같습니다.

user@host:~# ls -la .bash*
-rw------- 1 root root  4275 Aug 11 09:42 .bash_history_pts0
-rw------- 1 root root    75 Aug 11 09:49 .bash_history_pts1
-rw-r--r-- 1 root root  3120 Aug 11 10:09 .bashrc

3

여기서 나는 하나의 문제를 지적 할 것이다.

export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"

PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"

source ~ / .bashrc를 실행하면 $ PROMPT_COMMAND는 다음과 같습니다.

"history -a; history -c; history -r history -a; history -c; history -r"

"history -a; history -n history -a; history -n"

이 반복은 'source ~ / .bashrc'를 실행할 때마다 발생합니다. 'echo $ PROMPT_COMMAND'를 실행하여 'source ~ / .bashrc'를 실행할 때마다 PROMPT_COMMAND를 확인할 수 있습니다.

"history -n history -a"와 같은 일부 명령이 깨져있는 것을 볼 수 있습니다. 그러나 좋은 소식은 다른 부분은 여전히 ​​유효한 명령 시퀀스를 형성하기 때문에 여전히 작동한다는 것입니다 (일부 명령을 반복적으로 실행하여 추가 비용이 발생하지만 깨끗하지는 않습니다)

개인적으로 나는 다음과 같은 간단한 버전을 사용합니다.

shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r"

위에 언급 된 것과 같은 문제는 없지만 대부분의 기능을 가지고 있습니다.

또 다른 요점은 : 마술이 전혀 없다는 것 입니다. PROMPT_COMMAND는 단순한 bash 환경 변수입니다. bash 프롬프트 ($ 기호)를 받기 전에 명령이 실행됩니다. 예를 들어 PROMPT_COMMAND는 "echo 123"이며 터미널에서 "ls"를 실행합니다. 효과는 "ls; echo 123"을 실행하는 것과 같습니다.

$ PROMPT_COMMAND="echo 123"

출력 ( 'PROMPT_COMMAND = "echo 123"; $ PROMPT_COMMAND'실행과 동일) :

123

다음을 실행하십시오.

$ echo 3

산출:

3
123

"history -a"는 메모리의 히스토리 명령을 ~ / .bash_history에 쓰는 데 사용됩니다.

"history -c"는 메모리에서 히스토리 명령을 지우는 데 사용됩니다.

"history -r"은 ~ / .bash_history에서 메모리로 기록 명령을 읽는 데 사용됩니다.

http://ss64.com/bash/history.html : 역사 명령 설명을 참조하십시오

추신 : 다른 사용자들이 지적했듯이, 수출 은 불필요합니다. 참조 : .bashrc에서 내보내기 사용


2

세션 또는 작업별로 내역 파일을 설정하는 스크립트를 작성하여 다음을 기반으로합니다.

        # write existing history to the old file
        history -a

        # set new historyfile
        export HISTFILE="$1"
        export HISET=$1

        # touch the new file to make sure it exists
        touch $HISTFILE
        # load new history file
        history -r $HISTFILE

모든 기록 명령을 저장할 필요는 없지만 내가 관심있는 명령을 저장하고 검색하기가 더 쉬워 모든 명령을 통과합니다. 내 버전에는 모든 기록 파일이 나열되어 있으며 모든 기록 파일을 검색하는 기능이 있습니다.

전체 소스 : https://github.com/simotek/scripts-config/blob/master/hiset.sh


2

다음 은 개별 세션의 기록을 섞지 않는 솔루션입니다 !

기본적으로 각 세션의 기록을 개별적으로 저장하고 모든 프롬프트에서 다시 만들어야합니다. 예, 더 많은 리소스를 사용하지만 들리는 것처럼 느리지는 않습니다. 기록이 10 만 개가 넘는 경우에만 지연이 눈에 띄기 시작합니다.

핵심 논리는 다음과 같습니다.

# on every prompt, save new history to dedicated file and recreate full history
# by reading all files, always keeping history from current session on top.
update_history () {
  history -a ${HISTFILE}.$$
  history -c
  history -r
  for f in `ls ${HISTFILE}.[0-9]* | grep -v "${HISTFILE}.$$\$"`; do
    history -r $f
  done
  history -r "${HISTFILE}.$$"
}
export PROMPT_COMMAND='update_history'

# merge session history into main history file on bash exit
merge_session_history () {
  cat ${HISTFILE}.$$ >> $HISTFILE
  rm ${HISTFILE}.$$
}
trap merge_session_history EXIT

일부 안전 장치 및 성능 최적화를 포함한 전체 솔루션에 대해서는 이 요지 를 참조하십시오 .


1

이것은 ZSH에서 작동합니다

##############################################################################
# History Configuration for ZSH
##############################################################################
HISTSIZE=10000               #How many lines of history to keep in memory
HISTFILE=~/.zsh_history     #Where to save history to disk
SAVEHIST=10000               #Number of history entries to save to disk
#HISTDUP=erase               #Erase duplicates in the history file
setopt    appendhistory     #Append history to the history file (no overwriting)
setopt    sharehistory      #Share history across terminals
setopt    incappendhistory  #Immediately append to the history file, not just when a term is killed

불행히도 문제는 엄격하게 배쉬입니다 :-)
Jaleks

1
구글에서 자사의 첫 번째 결과 나뿐만 아니라 zsh을 검색 ... 그것은 도움이 될 생각
Mulki

3
~ "존재하지 않는 경우 여러 터미널 창에서 zsh 기록 유지"라는 새로운 질문을해야합니다. 좋은 질문이라면 자신의 질문에 대답하는 것도 좋습니다.
Oli

1

나는 이것을 오랫동안 원했다. 특히 새 프로젝트에서 다시 실행하기 위해 명령이 실행되는 곳에서 명령을 검색하거나 명령으로 디렉토리를 찾는 기능이 필요했다. 따라서이 도구를 함께 사용하면 글로벌 CLI 히스토리 저장을위한 이전 솔루션과 percol (C ^ R로 맵핑 됨)이라는 대화식 grepping 도구가 결합됩니다. 사용하기 시작한 첫 번째 머신에서 여전히 매끄러운 상태입니다. 이제 2 년 이상 된 CLI 내역이 있습니다.

화살표 키에 관한 한 로컬 CLI 기록을 엉망으로 만들지 않지만 전역 기록에 매우 쉽게 액세스 할 수 있습니다 (C ^ R 이외의 다른 것에 매핑 할 수도 있음)


이것은 zsh를위한 것입니까?
sjas

1
예, 처음에는 zsh 용으로 만들었습니다. bash와 fish에서도 작동합니다. 작동하는지 알려주세요. 나는 한 동안을 변경하지 않은 나는 내 설치 지침에 있었던 방법을 명확 모르겠어요
고든 웰스


-1

다음은 내 .bashrc의 스 니펫과 필요한 경우 간단한 설명입니다.

# The following line ensures that history logs screen commands as well
shopt -s histappend

# This line makes the history file to be rewritten and reread at each bash prompt
PROMPT_COMMAND="$PROMPT_COMMAND;history -a; history -n"
# Have lots of history
HISTSIZE=100000         # remember the last 100000 commands
HISTFILESIZE=100000     # start truncating commands after 100000 lines
HISTCONTROL=ignoreboth  # ignoreboth is shorthand for ignorespace and     ignoredups

HISTFILESIZE 및 HISTSIZE는 개인 취향이며 취향에 따라 변경할 수 있습니다.

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